PyQt:从回调更新 GUI

Posted

技术标签:

【中文标题】PyQt:从回调更新 GUI【英文标题】:PyQt: updating GUI from a callback 【发布时间】:2012-08-23 00:00:45 【问题描述】:

使用 Python3 和 PyQt4,我有一个函数 (run),它将一个可调用对象作为输入来提供状态更新。

class Windows(QtGui.QWidget):
    # Creates a widget containing:
    # - a QLineEdit (status_widget)
    # - a button, connected to on_run_clicked

    def on_run_clicked(self):
        def update(text):
            self.widget.setText(text)

        threading.Thread(target=run, args=(update, )).start()

这可以正常工作(即文本更新在小部件中正确显示)。但是,当我将 QLineEdit 替换为 QTextEdit 并使用 append 方法添加文本时,我得到:

QObject::connect: 无法将“QTextCursor”类型的参数排队

(确保使用 qRegisterMetaType() 注册“QTextCursor”。)

它仍然有效,但指出我做错了什么,我不确定当更多线程处于活动状态时我是否会继续工作。通常,我使用信号和插槽进行此类更新,但 run 函数不是 PyQt 特有的。问题是:

    为什么它在没有警告 QLineEdit 的情况下工作,而不是 QTextEdit? 处理这种情况的正确方法是什么?

【问题讨论】:

【参考方案1】:

我不知道一个类有效而另一个无效的具体原因——我也不知道使用 Python 线程与 Qt 的线程之间的区别......但是,我可以告诉你,这是非常如果你没有正确设置它。也就是说,您不能(或至少不应该)从线程修改 GUI 对象。同样,不确定 python 与 Qt 线程的区别。但是,从 GUI 修改界面的安全方法是向窗口发送信号……我知道的最简单的方法是通过 Qt 线程。

class MyThread(QtCore.QThread):
    updated = QtCore.pyqtSignal(str)

    def run( self ):
        # do some functionality
        for i in range(10000):
            self.updated.emit(str(i))

class Windows(QtGui.QWidget):
    def __init__( self, parent = None ):
        super(Windows, self).__init__(parent)

        self._thread = MyThread(self)
        self._thread.updated.connect(self.updateText)

        # create a line edit and a button

        self._button.clicked.connect(self._thread.start)

    def updateText( self, text ):
        self.widget.setText(text)

【讨论】:

This question 是解决 Python 与 Qt 线程问题的一个很好的起点。执行摘要:与Qt交互时始终使用Qt线程;否则,请使用 Python 线程。 当你不控制运行函数但你可以给它回调时,哪种方法是正确的?最简单的事情似乎是在回调函数上执行发射,对吧?此外,这篇帖子labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong 说你不应该继承 QThread,这是否也适用于 PyQt? 嗯,这很有趣——我以前从未见过。我将不得不更详细地阅读它。我在那个线程上镜像了 cmets,如果你不应该继承 QThread,那么他们的文档已经过时了...... @EricHulser 是的。情况似乎如此。这里有一篇有趣的 C++ 帖子 mayaposch.wordpress.com/2011/11/01/…

以上是关于PyQt:从回调更新 GUI的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GUI pyqt 中更新热图的颜色条?

PyQT和线程

Pyqt5--为啥 QApplication.processEvents() 更新 GUI 失败

PyQt5 GUI 仅在单击屏幕并重新打开时更新

PyQt:如何在不冻结 GUI 的情况下更新进度?

根据来自scrapy的信号更新主线程内的PyQt5 Gui