大家好!我在QPushButton实例上发现了一些奇怪的东西。哦,首先,我正在使用..
我的测试代码是......
# 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)。
我的代码出了什么问题?
感谢您阅读我的问题!请帮忙!
答案 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
信号连接到睡眠内部的方法时,事件循环没有机会完成信号处理并刷新接口的图像屏幕,就像处理信号后发生的那样。刷新的图形元素由内部发送的一系列信号完成。