PySide2 / QT for Python:窗口小部件未更新/ GUI冻结

问题描述 投票:1回答:2

我正在将pyside2与python结合使用。在Qmainwindow上,我创建了QpushButton和Qlabel。标签隐藏在mainWindow的初始位置,并且pushButton连接到mainWindow中定义的以下函数:

def buttonPushed(self):
        self.label.show()
        self.doStuff()
        self.label.hide()

“ doStuff()”函数需要15秒钟的执行时间,并且可以按预期工作,因此该标签此时应该可见,但不是可见的。如果删除“ self.label.hide()”,则标签会显示(当然,再也不会隐藏)。

“ doStuff()”函数调用pyside2的函数。我也尝试在self.label.show()之后添加一个self.label.update(),但这没什么区别。

我的猜测与QT如何安排任务有关:当我调用self.label.show()时,QT仅在buttonPushed()结束后才执行。

我该怎么办?

python pyside2
2个回答
3
投票

如果长时间执行任务,它将阻塞Qt事件循环,导致某些任务无法正常运行,因为无法传输事件,导致窗口冻结,并产生您所指示的效果。

因此,在这些情况下,您必须在另一个线程中执行该任务(假设该任务不会直接修改GUI),并通过信号将信息发送到GUI线程。在您的情况下,必须在执行繁重的任务之前发出一个信号,并且在将它们分别连接到QLabel的show和hide方法之后必须发出另一个信号。]

import threading

from PySide2.QtCore import Signal

class MainWindow(QMainWindow):
    started = Signal()
    finished = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)

        # ...

        self.started.connect(self.label.show)
        self.finished.connect(self.label.hide)

        self.button.clicked.connect(self.buttonPushed)

    def buttonPushed(self):
        threading.Thread(target=self.doStuff, daemon=True).start()

    def doStuff(self):
        self.started.emit()
        # heavy task
        self.finished.emit()

0
投票

@@ eyllanesc的解决方案在线程中的任务不涉及QT时起作用。否则应使用QThread和Qthreadpool。我用这个tutorial来了解如何做,但这是一个小例子:

© www.soinside.com 2019 - 2024. All rights reserved.