首页 > 解决方案 > 使用多线程的 Python PyQt 动态小部件生成

问题描述

我正在编写一个简单的程序,它读取写入文件的新输入并将其显示在弹出窗口中。

我将 PyQt5 用于:
A) 文件更改 (QtCore)
B) 窗口 (QtWidgets)

请注意,根据 PyQt 参考指南,我确实有一个使用信号的工作模型。但无法弄清楚以下内容,因此我不了解事情是如何运作的。

在测试实现时,我遇到了多线程问题。这是我的问题的简化示例:

from PyQt5 import QtWidgets
import sys
import threading

def additem(window):
    """ generates label in window at bottom """
    print("Adding label to window on thread {}".format(threading.currentThread()))
    row = window.layout().rowCount() + 1
    btn = QtWidgets.QPushButton('button_' + str(row), window)
    window.layout().addWidget(btn,row,1)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QWidget()
    w.setLayout(QtWidgets.QGridLayout())
    # set to timers after 3,6 will generate label in window
    threading.Timer(3,additem,args=(w,)).start()
    threading.Timer(6,additem,args=(w,)).start()
    w.show()
    sys.exit(app.exec_())

输出:

向窗口
QObject::setParent 添加标签:无法设置父级,新父级在不同的线程中

我尝试设置全局队列来传递对象,但仍然是同样的错误。

尽管我现在为什么会引发异常,但我不明白如何避免它。

一种尝试是直接传递顶部对象“app”,然后按索引获取窗口(app 是顶部父对象):

...
threading.Timer(3,additem,args=(app,)).start()
...

def additem(app):
    w = app.allWidgets()[0]
    ...

我知道PyQt是一个用python包裹的C库,但我对C不熟悉。app对象是指向内存堆中对象的指针,
为什么不能操作该对象?
对象是在新线程中复制的吗?(以为我仍然可以“更新”该对象)

标签: pythonpython-3.xpyqtpyqt5python-multithreading

解决方案


推荐阅读