【发布时间】:2015-04-19 22:32:11
【问题描述】:
代码很繁重,所以我将发布一些sn-ps。
class Program(QtGui.QWidget):
def __init__(self, parent=None):
super(Program, self).__init__(parent)
...
def main():
app = QtGui.QApplication(sys.argv)
global ex
ex = Program()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在这中间我有一堆标签、文本字段、按钮和 4 个 QListWidgets 在子布局中,这些子布局被添加到网格中。
我根据输入启动可变数量的线程。通常是 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 中完成此操作,我可以看到列表项动态显示在 ListBox 小部件中,而不会冻结 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"
我做错了什么?
【问题讨论】:
-
不确定您是否知道这一点,但仅从
Thread继承不足以使一段代码成为多线程的。例如,对于从threading.thread继承的线程,您需要将所需的代码放入其run方法中,然后在某个时候调用start。出现在__init__方法中的代码仍将在主线程中运行。 -
感谢您的回复。这有点复杂。我已经更新了我的问题以回答您的评论。首先,我在我的 Program 类函数中列出线程。然后我将此列表发送到一个线程类,该线程类启动并加入线程,以便我可以找出所有线程何时完成。当这些线程启动(myThread 类)时,它们会在我想要更新我的 GUI 的 Program 类中再次调用一些函数。
-
也许我从 Thread() 函数中错误地调用了 Program() 函数?我很挣扎,因为起初我试图通过简单的 Program.some_function(arguments).. 来调用它们,但不断收到关于程序实例未通过的错误。所以我不得不通过将“ex”声明为全局变量并将其作为 Program() 实例参数传递来提出一个肮脏的(?)修复。这是正确的做法吗?
-
将程序实例添加到线程的“官方”方法是在线程的
run定义中添加一个参数并像thread.start(args = (my_program_instance,))一样启动线程,但是全局变量应该可以工作也。一般来说,您的spawnAndWaitThreadsThread对我来说看起来不错。我认为我要寻找问题的下一个地方是myThread -
所以如果一个人浏览了成百上千个文件(os.path.listdir),通过一些扩展过滤它们,提取它们的时间戳,将结果连接到一个字符串,然后尝试写入一个将这数百个字符串动态分配给多个 QListWidget,它不应该冻结程序,对吧?
标签: python multithreading user-interface pyqt4 freeze