0

这是示例代码

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_()

在这里,我有一个带有列表小部件和一个按钮的基本 GUI。当我按下按钮时,我的程序应该稍等片刻,并在该列表小部件中显示一个字符串。WorkThread 类执行等待的工作,等待后它会发出一个信号。但是当我运行程序时,只有我可以看到 GUI,而 listwidget 中什么也没有显示。

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

4

2 回答 2

2

QListWidget.addItems需要一个项目列表,但你给它一个QString. 你应该使用.addItem.

还有一些小的更正。你不需要__del__在你的线程中实现。__init__如果你不做额外的事情,你可以跳过。你应该使用新风格的信号和连接

这是所有更正的结果:

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_())
于 2013-02-12T19:12:32.543 回答
1

PyQtWiki 包含一个非常详细的示例,如何将信号从后台线程发送到 UI。显然,只要您QThread实现线程,就不需要特殊的魔法。

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

于 2013-02-12T16:43:28.630 回答