基本GUI中的QThread解决方法

时间:2013-02-12 16:21:27

标签: pyqt

以下是示例代码

import sys, time
from PyQt4 import QtCore, QtGui

class MyApp(QtGui.QWidget):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setGeometry(300, 300, 280, 600)
        self.setWindowTitle('threads')
        self.layout = QtGui.QVBoxLayout(self)
        self.testButton = QtGui.QPushButton("test")
        self.connect(self.testButton, QtCore.SIGNAL("released()"), self.test)
        self.listwidget = QtGui.QListWidget(self)
        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.listwidget)

    def add(self, text):
        print "Add: ", text
        self.listwidget.addItems(text)
        self.listwidget.sortItems()

#    def addBatch(self, text="test", iters=6, delay=0.3):
#        for i in range(iters):
#            time.sleep(delay)
#            self.add(text + "  " + str(i))

    def test(self):
        self.listwidget.clear()
        #self.addBatch("_non_thread", iters=6, delay=0.3)
        self.workThread = WorkThread()
        self.connect(self.workThread, QtCore.SIGNAL("update(QString"), self.add)
        self.workThread.start()

class WorkThread(QtCore.QThread):

    def __init__(self):
        QtCore.QThread.__init__(self)

    def __del__(self):
        self.wait()

    def run(self):
        for i in range(6):
            time.sleep(0.3)
            self.emit(QtCore.SIGNAL('update(QString'), "from work thread " + str(i))
        return

app = QtGui.QApplication(sys.argv)
test = MyApp()
test.show()
app.exec_()

这里我有一个带有listwidget和按钮的基本GUI。当我按下按钮时,程序应该等待片刻并在该listwidget中显示一个字符串。 WorkThread类执行等待的东西,等待它后发出一个信号。但是当我运行程序时,只有我可以看到GUI,并且listwidget中没有显示任何内容。

有人可以告诉我这背后的原因是什么以及如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

QListWidget.addItems需要一个项目列表,但您只需要一个QString。您应该使用.addItem

还有一些小的修正。您不需要在线程中实现__del__。如果您没有做其他事情,可以跳过__init__。你应该使用new style signals and connections

以下是所有更正的结果:

import sys, time
from PyQt4 import QtCore, QtGui


class MyApp(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setGeometry(300, 300, 280, 600)
        self.setWindowTitle('threads')
        self.layout = QtGui.QVBoxLayout(self)
        self.testButton = QtGui.QPushButton("test")
        self.testButton.clicked.connect(self.test)
        self.listwidget = QtGui.QListWidget(self)
        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.listwidget)

    def add(self, text):
        print "Add: ", type(text)
        self.listwidget.addItem(text)
        self.listwidget.sortItems()

#    def addBatch(self, text="test", iters=6, delay=0.3):
#        for i in range(iters):
#            time.sleep(delay)
#            self.add(text + "  " + str(i))

    def test(self):
        self.listwidget.clear()
        #self.addBatch("_non_thread", iters=6, delay=0.3)
        self.workThread = WorkThread()
        self.workThread.update.connect(self.add)
        self.workThread.start()


class WorkThread(QtCore.QThread):
    update = QtCore.pyqtSignal(str)

    def run(self):
        for i in range(6):
            time.sleep(0.3)
            self.update.emit("from work thread " + str(i))

app = QtGui.QApplication(sys.argv)
test = MyApp()
test.show()
sys.exit(app.exec_())

答案 1 :(得分:1)

The PyQtWiki contains a pretty elaborate example如何将信号从后台线程发送到UI。显然,只要你QThread实现你的线程,就不需要特别的魔法。

但我注意到您使用信号released()将按钮与方法test()连接起来。你试过clicked()吗?