如何使用Qthread更新表格?

时间:2017-05-13 06:24:52

标签: python python-2.7 pyqt pyqt4

在我的实际应用程序中,我正在尝试使用大量数据更新qtablewidget。问题是表更新需要一段时间,并且gui在执行时几乎被冻结。我写了一小段我基本上想做的事情。 我想做同样的事情,但通过Qthread完成更新,因为这将有助于保持gui活跃,我不知道该怎么做。我已经尝试了QtGui.qApp.processEvents(),但它仍然太迟了,这就是我需要一个线程的原因。请指教。

这是我想要做的一个小例子。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui


class TryingStuff(QtGui.QDialog):
    def __init__(self, parent=None):
        super(TryingStuff, self).__init__(parent)
        self.setWindowTitle("Trying stuff")
        self.doJob = QtGui.QPushButton()
        self.closebutton = QtGui.QPushButton()
        self.closebutton = QtGui.QPushButton()
        self.closebutton.setText('Close')
        self.closebutton.setMaximumWidth(150)
        self.closebutton.clicked.connect(self.close)
        self.doJob.setText("do job")
        self.doJob.setMaximumWidth(100)
        self.table = QtGui.QTableWidget()
        self.setUpTable(self.table)
        self.doJob.clicked.connect(lambda: self.putStuffInA(self.table))
        self.table.verticalHeader().hide()
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.addWidget(self.doJob, 0,  QtCore.Qt.AlignRight)
        self.verticalLayout.addWidget(self.table)
        self.verticalLayout.addWidget(self.closebutton, 0, QtCore.Qt.AlignRight)
        # self.connect(self.worker, QtCore.SIGNAL("updateTable(QString)"), self.updateTable)


    def setUpTable(self, table):
        table.setColumnCount(2)
        table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Col 1"))
        table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("Col 2"))

        table.setMinimumWidth(500)
        header = table.horizontalHeader()
        header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
        #header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)
        table.horizontalHeader().setStretchLastSection(True)

    def putStuffInA(self, table):
        a = 0
        lista =[]
        while a < 10:
            print a
            lista.append(a)
            a += 1
        table.setRowCount(len(lista))
        self.populateTable(lista, table)

    def populateTable(self, lista, table):
        try:
            for i in lista:
                desc = QtGui.QTableWidgetItem()
                buttonA = QtGui.QPushButton()
                #buttonA.clicked.connect(self.printing(i))
                buttonA.setText("A")
                desc.setText(str(i))
                table.setItem(i, 0, desc)
                QtGui.qApp.processEvents()
                table.setCellWidget(i, 1, buttonA)
                QtGui.qApp.processEvents()
        except Exception:
            pass

    def printing(self, i):
        print i

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    k = TryingStuff()
    k.show()
    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:0)

这可能会帮助您入门,如果它没有帮助,请告诉我:)基本上,您创建一个Worker,它将在QThread为您完成工作。当您点击doJob按钮时,它会调用Worker的方法(请注意,如果您需要为此计算设置一些参数,请在强调之前)。计算完成后,它会将信号computationFinished发送回TryingStuff个对象。通过将此信号连接到putStuffInA方法,您可以在表格中填入数据。

class MyWorker(QtCore.QObject):
    computationFinished = QtCore.pyqtSignal() # emited when simulations is finished

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)

        self.dataForTable = []
        # or some other needed attributes

        self.TheWorker = QtCore.QThread()
        self.moveToThread(self.TheWorker)
        self.TheWorker.start()

    def calculateData(self):
        # do some calculations here
        # and fill self.dataForTable
        # or some other variables needed for yout tables
        self.computationFinished.emit() # emit the signal

class TryingStuff(QtGui.QDialog):
    def __init__(self, parent=None):
        super(TryingStuff, self).__init__(parent)

        # blah blah

        self.table = QtGui.QTableWidget()
        self.setUpTable(self.table)

        # blah blah

        self.worker = MyWorker()
        self.doJob.clicked.connect(self.worker.calculateData)
        self.worker.computationFinished.connect(self.putStuffInA)

    def putStuffInA(self):
        # here use self.worker.dataForTable
        # to fill data for self.table