PyQt 4 UI 冻结

Posted

技术标签:

【中文标题】PyQt 4 UI 冻结【英文标题】:PyQt 4 UI freezes 【发布时间】:2009-12-20 20:15:40 【问题描述】:

下面的程序应该只是计数和 int 并在标签中显示它的值。 但过了一会儿,GUI 停止工作,而循环继续。

from PyQt4 import QtGui,QtCore
import sys

class main_window(QtGui.QWidget):
    def __init__(self,parent=None):
        #Layout       
        QtGui.QWidget.__init__(self,parent)
        self.bt=QtGui.QPushButton('crash')
        self.lbl=QtGui.QLabel('count')
        ver=QtGui.QHBoxLayout(self)
        ver.addWidget(self.bt)
        ver.addWidget(self.lbl)
        self.cnt=0
        self.running=False
        self.connect(self.bt,QtCore.SIGNAL("clicked()"),self.count)

    def count(self):
        self.running=True
        while self.running:
            self.cnt+=1
            print self.cnt
            self.lbl.setText(str(self.cnt))
            self.repaint()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    mw=main_window()
    mw.show()
    sys.exit(app.exec_())   

有什么帮助吗?

【问题讨论】:

【参考方案1】:

你没有让 Qt 的事件循环运行,所以 GUI 没有响应。此外,不需要repaint()QLabel.setText() 将重新绘制标签。它所做的只是排队一个额外的绘画事件,但这永远不会得到处理。

您需要做的是将self.repaint() 替换为QtGui.QApplication.processEvents()。这将使应用有机会在您处于循环状态时处理任何未决事件(包括重绘以及 ui 交互)。

【讨论】:

QtGui.QGuiApplication.processEvents() in pyQt5【参考方案2】:
def count(self):
    self.running=True
    while self.running:
        self.cnt+=1
        print self.cnt
        self.lbl.setText(str(self.cnt))
        self.repaint()

你有没有想过从这个无限循环中退出?例如。 self.running=False. GUI 可能会停止工作,因为它没有足够的时间来执行repaint。您可能需要在循环中添加一些 time.sleep 以等待 GUI 重新绘制。

更新:你应该使用QTimer,而不是简单的while循环,来实现你正在实现的行为。

【讨论】:

我试图尽可能简化我的问题,所以是的,计划了一个停止按钮。输入 time sleep 命令甚至会使 gui 更快崩溃。 你最好使用 QTimer(doc.trolltech.com/3.3/qtimer.html) 而不是 while 循环并根据需要启动/停止它。 此外,如果您使用单线程,则只要执行 while 循环,您的停止按钮就不起作用。所以,正如我所提到的,尝试使用 QTimer。 好的,可以使用 0 毫秒的 QTimer 来代替它。谢谢。【参考方案3】:

你必须让主事件循环运行,这是你没有做的事情。

【讨论】:

对不起,我对 pyqt 还很陌生,但是绘画调用主循环吗?

以上是关于PyQt 4 UI 冻结的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 应用程序 - 使用计时器运行带有循环的函数使其“冻结”

Pyqt Gui 在循环中冻结

PYQT资源,冻结程序

pyqt4中的线程

如何修复 PyQt5 GUI 冻结

PyQt5:调用长时间运行的函数时 QMainWindow 冻结