1

フェードアウトしたいボタン ウィジェットがあります ( self.button1)

def button_slot(self):
    fade_effect = QtGui.QGraphicsOpacityEffect()
    self.button1.setGraphicsEffect(fade_effect)
    hideAnimation = QtCore.QPropertyAnimation(fade_effect, "opacity")
    hideAnimation.setDuration(5000)
    hideAnimation.setStartValue(1.0)
    hideAnimation.setEndValue(0.0)
    hideAnimation.start(QtCore.QPropertyAnimation.DeleteWhenStopped)
    self.hideAnimation = hideAnimation

コードは PyQt にありますが、元の Qt と同じです。

理由により、テストファイルでコードを個別に試すと、うまく機能します。ただし、コードに統合しようとすると、フェードアウト アニメーションがバックグラウンドで実行されているように見えますが、GUI 自体では更新されていません。

  • ボタンが「クリックされた」状態でスタックします。
  • ウィンドウを最小化して拡大すると、ボタンの不透明度は本来あるべき場所になります (たとえば、期間が 1.0 から 0.0 までの 5000 ミリ秒の場合、2500 ミリ秒後にウィンドウを拡大すると 0.5 の不透明度が表示されます)。
  • 「動かなくなった」ように見えますが、ボタンはクリック可能です。

なぜこれが起こっているのでしょうか?イベントの反復ごとに GUI を強制的に更新するにはどうすればよいですか?

4

1 に答える 1

1

私が持っている唯一の可能な説明は、コード内のどこかでイベントループをブロックしているということです。テストケースが示すように、アニメーションは確実に実行されますが、イベントループから呼び出されます。コードがブロックされた場合-コード内に物事を待ったり、スリープしたりする場所がある場合、それが問題です。

Qtおよび他の多くのフレームワークのGUIコードは、実行から完了までの方法で作成する必要があります。すべてのスロットとイベントハンドラーは、可能な限り迅速に実行してから戻る必要があります。スロットにブレークポイントを追加し、コードが停止したときにスタックトレースを見ると、そこにあることがわかりますQEventLoop::exec()。最終的に、すべてのGUIコードはイベントループから呼び出されます。

問題がなくなるまで、コードを区分的に減らしてみてください。これにより、ブロッキング部分がどこにあるかを知ることができます。Qtは、残念ながら、という名前の多くのメソッドを提供し、waitxxx()それらがイベントループをブロックすることを理解せずに使用される傾向があります。ブロックされたイベントループは、アプリケーションがユーザーの操作に応答しないことを意味し、最終的にOSはそれを検出し、回転するビーチボール(OS X)、回転するサークル(Vista / Win7)、またはスタックしたアプリケーションに関するメッセージを発行します。回転するビーチボール/サークルは、アプリケーションのメインイベントループがブロックされていることを意味します。

于 2012-06-17T12:46:25.393 に答える