如何使按钮立即禁用?

时间:2015-11-27 10:03:50

标签: python pyqt


大家好!我在QPushButton实例上发现了一些奇怪的东西。哦,首先,我正在使用..

  • windows 7
  • python 3.4
  • PyQt5

我的测试代码是......

# coding: utf-8

import sys, time
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.targetBtn = QPushButton('target', self)
        self.targetBtn.move(100, 100)
        self.targetBtn.clicked.connect(self.sleep5sec)

        self.setGeometry(100, 100, 300, 300)
        self.show()

    def sleep5sec(self):
        self.targetBtn.setEnabled(False)
        time.sleep(5)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我想要的是......当用户按下目标按钮时,该按钮立即被禁用。但在我的代码中,目标按钮在睡眠后被禁用(5)。

我的代码出了什么问题?

感谢您阅读我的问题!请帮忙!

2 个答案:

答案 0 :(得分:5)

正如我在评论和@MichalF中链接的thread中所建议的那样,python' s sleep完全冻结了UI,因此它不允许.setEnabled方法更新。

在Qt中,所有事件都是使用UI的主线程(这是另一个工作者)来管理的,因此像.setEnabled这样的操作在UI中没有立即生效(需要稍微重新绘制它)。使用time.sleep UI线程冻结,因此,Qt的主要工作人员不会更新(重新绘制)UI,直到计时器结束。

更改它的方法是使用PyQt5.QtCore.QTimer:

def sleep5sec(self):
    self.targetBtn.setEnabled(False)
    QTimer.singleShot(5000, lambda: self.targetBtn.setDisabled(False))

以上示例将立即禁用targetBtn,并在5秒后重新启用它。

答案 1 :(得分:2)

经验法则:在GUI应用程序中不要使用sleep()

几乎任何类型的GUI应用程序都可以在名为event loop的东西中运行,它是响应从操作系统(或Windows系统)传递的事件的单线程机制。如果你在那里睡觉,你的事件循环就不起作用了。

当您将clicked信号连接到睡眠内部的方法时,事件循环没有机会完成信号处理并刷新接口的图像屏幕,就像处理信号后发生的那样。刷新的图形元素由内部发送的一系列信号完成。