PyQt-GUI在Python中进行多线程处理时冻结,直到线程完成
代码相当繁重,因此我将只发布一些代码片段PyQt-GUI在Python中进行多线程处理时冻结,直到线程完成,python,multithreading,user-interface,pyqt4,freeze,Python,Multithreading,User Interface,Pyqt4,Freeze,代码相当繁重,因此我将只发布一些代码片段 class Program(QtGui.QWidget): def __init__(self, parent=None): super(Program, self).__init__(parent) 在子布局中,我有一堆标签、文本字段、按钮和4个QListWidget,这些子布局被添加到网格中 我根据输入启动不同数量的线程。通常为4条螺纹。它们在自己的类中启动: class myThread(Thread): def
class Program(QtGui.QWidget):
def __init__(self, parent=None):
super(Program, self).__init__(parent)
在子布局中,我有一堆标签、文本字段、按钮和4个QListWidget,这些子布局被添加到网格中
我根据输入启动不同数量的线程。通常为4条螺纹。它们在自己的类中启动:
class myThread(Thread):
def __init__(self, arguments, more_arguments):
threading.Thread.__init__(self)
def work_it(self, argument, more_arguments):
Program.some_function_in_Program_class(ex, arguments)
从那里我调用Program()类中的函数来对GUI进行实际更改
Program.generate_results(ex, arguments, arguments2, more_arguments)
最后,它归结为我迭代的列表,以及我是打印每个元素还是使用:
my_listbox.addItem(item)
它将冻结GUI,直到所有4个线程都完成列表。然后所有结果一起显示,而不是逐个显示
我已经在Tkinter中完成了这项工作,我可以看到列表框小部件中动态出现一个接一个的列表项,而不会冻结GUI
至于管理线程,我所做的是在一个列表上进行迭代,并根据其长度生成若干线程:
threadlist = []
for i in self.results:
sub_thread = myThread(i, self.results[i])
self.threadlist.append(sub_thread)
swapAndWaitThread = spawnAndWaitThreadsThread(self.threadlist)
swapAndWaitThread.start()
我这样做是为了能够管理这4个线程,并能够告诉他们何时完成
class spawnAndWaitThreadsThread(Thread):
def __init__(self, threadlist):
threading.Thread.__init__(self)
self.threadlist = threadlist
def run(self):
for thread in self.threadlist:
thread.start()
for thread in self.threadlist:
thread.join()
print "threads finished.. do something"
我做错了什么?我解决了这个问题,在只有一个作业的主程序()类中添加了一个非常简单的函数——启动一个非常简单的线程,该线程又返回到Program()类,并在那里调用一个函数,然后开始构建我的线程列表,将它们发送到另一个线程类,等等
因此,GUI不再冻结。不确定您是否知道这一点,但仅仅继承
线程
不足以使一段代码成为多线程的。例如,对于从继承的线程,需要将所需代码放入其run
方法中,然后在某个点调用start
。出现在\uuu init\uu
方法中的代码仍将在主线程中运行。感谢您的响应。这有点复杂。我已经更新了我的问题以回答您的评论。首先,我在程序类函数中列出一个线程列表。然后我将这个列表发送给一个线程类,该类启动并连接线程,这样我就可以知道所有线程何时完成。当这些线程启动(myThread类)时,它们会再次调用程序类中的某个函数,我想从中更新GUI。也许我从Thread()函数中调用Program()函数是错误的?我很挣扎,因为一开始我试图通过简单的程序调用它们。一些函数(参数)。。但不断收到程序实例未被传递的错误。因此,我必须通过将“ex”声明为一个全局变量并将其作为Program()实例参数传递来解决这个问题。这是正确的方法吗?将程序实例添加到线程的“官方”方法是向线程的run
定义中添加一个参数,然后像thread.start(args=(my_program\u instance,)
那样启动线程,但全局变量也应该可以工作。一般来说,您的spawandwaitthreadsthread
在我看来是正常的。我想下一步我要寻找问题的地方是myThread
,因此如果一个人浏览成百上千的文件(os.path.listdir),通过一些扩展名过滤它们,提取它们的时间戳,将结果连接到一个字符串,然后尝试一个接一个地将这数百个字符串动态写入多个QListWidgets它不应该冻结程序,对吗?没有得到。如果你不能写出你的实际代码,请举例说明
class spawnAndWaitThreadsThread(Thread):
def __init__(self, threadlist):
threading.Thread.__init__(self)
self.threadlist = threadlist
def run(self):
for thread in self.threadlist:
thread.start()
for thread in self.threadlist:
thread.join()
print "threads finished.. do something"