python - 从 QThread 生成并插入到 QTreeWidget 中的 QWidget 的正确父子关系

标签 python multithreading pyqt widget

我有一个 QTreeWidget,需要填充大量信息。这样我就可以按照我真正想要的方式设置它的样式和设置,我决定创建一个 QWidget,它的样式和外观都非常漂亮。然后,我将使用通用 TreeWidgetItems 填充 TreeWidget,然后使用 setItemWidget 将自定义 QWidget 粘贴到树中。当在主 PyQt 线程内调用 QWidget 时,这是有效的,但由于存在大量信息,我想在线程中创建并填充 QWidget,然后稍后发出它们以将其添加到主线程中一旦它们全部填满。然而,当我这样做时,QWidgets 似乎没有正确设置它们的 parent ,因为它们都在自己的小窗口中打开。以下是重现此问题的一些示例代码:

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class ItemWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        btn = QPushButton(self)

class populateWidgets(QThread):
    def __init__(self):
        QThread.__init__(self)

    def run(self):
        widget = ItemWidget()
        for x in range(5):
            self.emit(SIGNAL("widget"), widget)

class MyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(2)
        self.setCentralWidget(self.tree)

        self.pop = populateWidgets()
        self.connect(self.pop, SIGNAL("widget"), self.addItems)
        self.pop.start()

        itemWidget = QTreeWidgetItem()
        itemWidget.setText(0, "This Works")
        self.tree.addTopLevelItem(itemWidget)
        self.tree.setItemWidget(itemWidget, 1, ItemWidget(self))        

    def addItems(self, widget):
        itemWidget = QTreeWidgetItem()
        itemWidget.setText(0, "These Do Not")
        self.tree.addTopLevelItem(itemWidget)
        self.tree.setItemWidget(itemWidget, 1, widget)

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ui = MyMainWindow()
    ui.show()
    sys.exit(app.exec_())

如您所见,在 MyMainWindow 中执行此操作很好,但一旦在线程中处理并返回,就会出现问题。这可以吗?如果是这样,我如何正确地将 QTreeWidgetItem 内的 ItemWidget 类作为父级?提前致谢。

最佳答案

AFAICT Qt 不支持在实例化 QApplication 对象的线程(即通常是 main() 线程)之外的线程中创建 QWidget。以下是一些关于该主题的帖子以及 Qt 开发人员的回复:

http://www.qtcentre.org/archive/index.php/t-27012.html

http://www.archivum.info/qt-interest@trolltech.com/2009-07/00506/Re-(Qt-interest)-QObject-moveToThread-Widgets-cannot-be-moved-to-a-new-thread.html

http://www.archivum.info/qt-interest@trolltech.com/2009-07/00055/Re-(Qt-interest)-QObject-moveToThread-Widgets-cannot-be-moved-to-a-new-thread.html

http://www.archivum.info/qt-interest@trolltech.com/2009-07/00712/Re-(Qt-interest)-QObject-moveToThread-Widgets-cannot-be-moved-toa-new-thread.html

(如果可能的话,这样做的方法是从主线程内调用 QWidget 上的 moveToThread() 将它们移动到主线程 - 但显然该技术不能可靠地工作,对于QtCore 对尝试这样做的人进行了检查,向标准输出打印警告,告诉他们不要这样做)

关于python - 从 QThread 生成并插入到 QTreeWidget 中的 QWidget 的正确父子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11036184/

相关文章:

python - 从 pandas 数据框创建句子

python - 如何以脆皮形式在日期字段上显示日期选择器日历?

java - 我可以在 Scala 中将本地 var 作为 Volatile,因为在 Java 中这是不可能的吗?

python - 从 PyQt 中的 QTextEdit 获取可见文本

qt - 使用委托(delegate) (PySide/Qt/PyQt) 将项目的文本垂直居中

python - URL 以/开头时 XML2PDF 抛出异常

python - 如何在 python 中一起传递默认和可变长度参数?

c# - SqlConnections、Parallel.For、一个旧的 C# 应用程序和随机挂起初始化 SqlConnections

c++ - 如何在 C++ 中实现线程安全引用计数

python - QTreeWidget 的迭代