2016-10-21 11 views
1

を超えて、私はQDialogでQListWidgetを持っている、と私はすべてのホイールイベントがリストにリダイレクトされるようにしたいので、私はこれをしなかった:PyQtはwheelEventリダイレクションと最大再帰深度が

class Form(QDialog): 
    def __init__(self): 
    ... 
     self.myList = QListWidget() 
    ... 
    def wheelEvent(self, scrollEvent): 
     if not scrollEvent.isAccepted(): 
      scrollEvent.accept() 
      self.myList.wheelEvent(scrollEvent) 

それがスクロールするまで正常に動作しますアクションはリストを限界を超えて移動しようとします。そのような場合、QListWidgetはスクロールイベントを受け入れ(無視する)、それを親のフォーム(QListWidgetに再度送信する)に送信(無視)して、「最大再帰深度を超えましたエラーメッセージが表示されます。

QListWidgetにリダイレクトされる前にイベントが受け入れられた場合、Qdialogが再びQListWidgetにリダイレクトされるのはなぜですか?イベントの「受け入れ」フラグが保持されていないか(またはQListWidgetが「受け入れられません」に戻す)、QDialogに戻ったときに新しいイベントとして扱われます。これらのフラグを保持する方法、またはリストがトップ/ボトムにある場合でもQListWidgetでイベントを受け入れる方法はありますか?

私はQListWidgetのサブクラスを定義しようとしましたが、スーパークラスにリダイレクトする前にそのサブクラスでイベントを受け付けましたが、同じ結果、受け入れられなかったためにイベントがダイアログに戻ります。

EDIT:もう一度!今QListWidgetがイベントを処理していないとき(リストは、トップ/ボトムにある原因)イベントが再びQDialogに達したが、この二度目はにリダイレクトされません

class Form(QDialog): 
    def __init__(self): 
    ... 
     self.processingWheel = False 
     self.myList = QListWidget() 
    ... 
    def wheelEvent(self, scrollEvent): 
     if not self.processingWheel: 
      self.processingWheel = True 
      self.myList.wheelEvent(scrollEvent) 
      self.processingWheel = False 

:私は解決策を見つけましたもう一度QListWidgetを実行します。私は、それがQDialogの親にリダイレクトされていると仮定し、処理されます(何もしません)。

なぜ私は自分自身でフラグを管理しなければならなかったのかと疑問に思っています。最初の試行と同じようにイベントに関連付けられたisAccepted()フラグを使用できませんでした。 。私は、Qtでのイベントの伝播中に、イベントフラグのあるシーンの後ろで何が起こっているのか理解していないのが残念です。

答えて

1

NB:これはQt5に適用されます。Qt4ではこれが異なる場合があります。

self.myList.wheelEvent(scrollEvent)を呼び出すと、内部でQListView.wheelEvent(event)が呼び出され、新しいQWheelEventが作成され、適切なスクロールバーウィジェットに転送されます。スクロールバーがイベントを処理できない場合、受け入れられたフラグをfalseに設定します。この結果、イベントはとなり、すぐにがダイアログに再反映され、すべてが再び回ります。

イベントをリストウィジェットに送信すると、myList.wheelEvent()が返されるまで受け入れフラグを再設定することはできません。もちろん、リストウィジェットのスクロールバーがイベントを無視した場合は、never return、それはすぐに無限回帰に入ります。

イベントを転送する前にevent.flag()を呼び出すと、スクロールバーはデフォルトでfalseに再設定され、明示的にイベントを処理する場合にのみtrueに設定されるため、効果はありません。

これを考えると、外部フラグを使用したソリューションが唯一の実現可能なソリューションであるように思われます(blockSignalsメカニズムと多少似ています)。

+0

この場合、QListView.wheelEvent(イベント)を呼び出して、手動で「スロット」を呼び出して、新しいQWheelEventを生成していますか? – Pablovx

+0

私は、イベントをパラメータとして送信しています。新しいイベントを作成することは論理的ではないようです。 – Pablovx

+0

申し訳ありませんが、発見された改行だけがコメントセクションで受け付けられません。 ;)しかし、スクロールバーがデフォルトでイベントフラグをfalseに再設定するという事実は、常に同じイベントであり、新しいイベントが作成されない場合でも状況を説明します。ご協力いただきありがとうございます! – Pablovx

関連する問題