现在(仅为了解释)Main.process()函数和WorkerThread.run()函数是相同的。 它们通过从listWidget获取Main布局中的值来操作。 我希望我的workerthread类使用我在主列表小部件上设置的参数。
import sys, time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Main(QWidget):
def __init__(self, parent = None):
super(Main, self).__init__()
self.trdprocessbtn = QPushButton("Thread Processing")
self.guiprocessbtn = QPushButton("Main Processing")
self.listwidget = QListWidget()
for i in range(10):
self.listwidget.addItem(str(i))
layout = QVBoxLayout()
layout.addWidget(self.listwidget)
layout.addWidget(self.guiprocessbtn)
layout.addWidget(self.trdprocessbtn)
self.setLayout(layout)
self.guiprocessbtn.clicked.connect(self.process)
self.workerthread = WorkerThread()
self.trdprocessbtn.clicked.connect(self.startthread)
def startthread(self):
self.workerthread.start()
def process(self):
x = self.listwidget.currentItem().text()
for i in range(int(x)):
print "this is main processing ", i
time.sleep(1)
def dialogOpen(self):
dialog = Dialog()
dialog.exec_()
class WorkerThread(QThread):
def __init__(self, parent = None):
super(WorkerThread, self).__init__()
def run(self):
x = self.listwidget.currentItem().text()
for i in range(int(x)):
print "This is thread processing ", i
time.sleep(1)
app = QApplication(sys.argv)
form = Main()
form.show()
app.exec_()
答案 0 :(得分:1)
x = self.listwidget.currentItem().text()
方法中的第run
行很糟糕。您只能从主/ GUI线程访问小部件。
另一件事是,你的process
插槽阻塞了!永远不要阻止主线程(如果你阻止另一个线程,如果你不确定你做得对,你可能会做错了。)
一个简短的修复列表:
删除线程的run
方法,让Qt事件循环也在线程中运行。
将QListWidget::currentTextChanged(const QString & currentText)
信号连接到线程和主类中的新插槽,然后使该插槽启动/更新下一个提到的计时器和计数器。
使用QTimer
替换阻塞循环,将timeout
信号连接到一个插槽,该插槽执行您现在在循环中执行的操作。由于您睡眠1秒钟,您应该将计时器设置为每秒关闭一次。由于您只想运行一些设定的次数,所以将计数器变量添加到您的类中,并跟踪超时发生的次数,并在完成时关闭计时器。
如果您需要更复杂的列表数据处理,请在主类中为此创建一个插槽,并将相应的QListWidget
信号连接到它。然后向主类添加一个信号,其中包含线程的已处理数据,您将从此插槽中发出该数据。最后,为线程添加匹配槽,以处理线程中由您自己的信号发送的数据。你需要这样做,因为(我认为)只访问QListWidget的数据也不是线程安全的。