Eventloop未更新GUI小部件不透明度值

时间:2012-06-17 08:00:14

标签: qt qt4 pyqt4

我有一个按钮小部件,我想淡出(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不透明度。
  • 按钮是可点击的,即使它看起来像是卡住了#34;。

为什么会发生这种情况?如何强制GUI在每次事件迭代时更新自己?

1 个答案:

答案 0 :(得分:1)

我唯一可能的解释是你在代码中的其他地方阻止了事件循环。正如您的测试用例所示,动画肯定会运行,但它是从事件循环中调用的。如果您的代码阻塞 - 如果您的代码中有任何地方等待事情,睡眠等等,那么这就是您的问题。

Qt中的GUI代码和许多其他框架必须以运行到完成的方式编写。每个槽和事件处理程序必须尽可能快地执行,然后返回。在插槽中添加断点,并在代码停止时查看堆栈跟踪时,您会看到QEventLoop::exec()位于某处。最终,所有GUI代码都从事件循环中调用。

尝试逐段减少代码,直到问题消失。这就是你如何知道阻塞部分的位置。遗憾的是,Qt提供了许多名为waitxxx()的方法,并且它们倾向于在不理解它们阻止事件循环的情况下使用。阻塞事件循环意味着应用程序不响应用户交互,并且最终操作系统将检测到它并发出旋转沙滩球(OS X),旋转圈(Vista / Win7)或者可能是关于卡住应用程序的消息。旋转的beachball / circle表示应用程序的主事件循环被阻止。