简体   繁体   English

PyQt GUI冻结,直到线程完成,同时在Python中进行多线程处理

[英]PyQt GUI freezes until threads are finished while multithreading in Python

The code is pretty heavy so I will just post some snippets. 代码很重,所以我只发布一些片段。

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

And in between I have a bunch of labels, text fields, buttons and 4 QListWidgets inside sublayouts, these sublayouts are added to the grid. 在我之间我有一堆标签,文本字段,按钮和子布局内的4个QListWidgets,这些子布局被添加到网格中。

I'm launching variable number of threads depending on input. 我根据输入启动可变数量的线程。 Normally 4 threads. 通常是4个线程。 They are launched in own class: 它们是在自己的类中启动的:

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)

And from there I call functions inside the Program() class to do the actual changes to the GUI. 从那里我调用Program()类中的函数来对GUI进行实际更改。

Program.generate_results(ex, arguments, arguments2, more_arguments)

In the end it comes down to a list I iterate over and whether I print each element or I use: 最后,它归结为我迭代的列表以及是否打印每个元素或我使用:

my_listbox.addItem(item)

It freezes the GUI until all 4 threads are finished going through the list. 它会冻结GUI,直到所有4个线程完成通过列表。 Then all the results appear together instead of appearing one by one. 然后所有结果一起出现而不是一个一个地出现。

I have done this in Tkinter and I could see one by one list item appear in the ListBox widgets dynamically, without freezing the GUI. 我在Tkinter中做了这个,我可以看到ListBox小部件中的逐个列表项动态显示,而不会冻结GUI。

As for managing threads what I'm doing is I'm iterating over a list and according to its length I make a number of threads: 至于管理线程,我正在做的是迭代一个列表,根据它的长度,我创建了许多线程:

threadlist = []
for i in self.results:
    sub_thread = myThread(i, self.results[i])
    self.threadlist.append(sub_thread)
swapAndWaitThread = spawnAndWaitThreadsThread(self.threadlist)
swapAndWaitThread.start()

I do this to be able to manage these 4 threads and be able to tell when they are finished. 我这样做是为了能够管理这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"

What am I doing wrong? 我究竟做错了什么?

I resolved this issue by adding a very simple function in the main Program() class which has only one job - to start a very simple thread which in turn goes back to Program() class and calls a function there which then starts constructing my threads list, sending them to another thread class, etc. 我通过在只有一个作业的主Program()类中添加一个非常简单的函数来解决这个问题 - 启动一个非常简单的线程,然后又回到Program()类并调用一个函数然后开始构造我的线程列表,将它们发送到另一个线程类等。

As a result GUI is not freezing anymore. 结果,GUI不再冻结。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM