【问题标题】:How to pass variable to QThread (PySide or PyQT)如何将变量传递给 QThread(PySide 或 PyQT)
【发布时间】:2015-06-20 03:54:36
【问题描述】:

我真的很难完成编写一个需要多个不同线程的 GUI 应用程序。在高层次上,我需要:

一个 GUI 线程,它有一个按钮来打开用户选择目录的目录浏览器。在选择目录时,一个线程开始查找特定文件类型。这可能需要很长时间,所以我知道我需要放入一个单独的 QThread。

然后,一旦该 browseFile 线程完成了对文件的搜索,它就会返回一个 fileList,然后将其分块为子文件列表。然后将每个 subfileList 发送到单独的线程进行处理,这将花费大量时间。

这是我目前编写的代码:

from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtCore import * 
import os

class BrowseThread(QThread):
    processdone = QtCore.pyqtSignal("QString") # Define custom signal.

    def __init__(self, parent, *args, **kw):
        QThread.__init__(self, parent)
        self.search(*args, **kw)

    def search(self, directory_path):
        self.fileList = []
        self.count = 0
        for dirname, dirnames, filenames in os.walk(directory_path):
            for filename in filenames:
                if filename.endswith(".gz"):
                    self.fileList.append(os.path.join(directory_path,filename))

        self.emit( SIGNAL('processdone'), "DONE")

        return     

class MyClass(QObject):

    def __init__(self):            
        super(MyClass, self).__init__()

        directory_path = r'C:\Data'

        thread1 = BrowseThread(self, directory_path) 
        self.connect( thread1, SIGNAL("processdone"), self.thread1done)  
        thread1.start()  

    def thread1done(self, text):
        print(text)
        sys.exit()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)  
    a = MyClass()
    sys.exit(app.exec_())

有没有比使用 *args, **kw 更好的方法将目录路径传递给 browseThread?

如何将 fileList 返回到主线程,然后我可以将其传递给许多新的处理线程。

我确信我做的比应该做的更难,所以希望有人可以帮助我

谢谢

【问题讨论】:

    标签: python multithreading pyqt pyside


    【解决方案1】:

    我建议将您的代码设计更改为具有真正工作的工作类的解决方案。这个工作类将像这样移动到普通线程(我不知道 PyQt,但它应该与 C++ 版本非常相似):

    class SearchWorker(QObject):
        finished_sig = QtCore.pyqtSignal('')  # finished signal
    
        def __init__(self, your_stuff):
            self.directory_path = ...
    
        def process_slot(self):
            # use self.directory_path
            # your code
            self.emit(SIGNAL('finished_sig'), '')
    

    现在主要部分是将启动信号连接到 MyClass 类中的工人。 这在 C++ 中给出了类似的东西:

    QThread* thread = new QThread;
    Worker* worker = new Worker();
    worker->moveToThread(thread);
    // The start signal will actually launch your search method in the worker
    connect(thread, SIGNAL(started()), worker, SLOT(process_slot()));
    connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
    
    // May be useless in python
    connect(worker, SIGNAL(finished_sig()), worker, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    

    好处是您可以在有或没有线程的情况下使用 worker,并且您可以通过 setter 方法轻松地将参数传递给 worker。

    要了解有关线程的 Qt 信号和插槽的更多信息,我建议您阅读:

    【讨论】:

      【解决方案2】:

      你应该能够使用 QT 的信号和槽机制。

      http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads

      您也可以使用消息传递系统。

      将它作为 arg 传递也没有错。请确保您安全地进行操作:https://web.archive.org/web/20150423115746/http://effbot.org/zone/thread-synchronization.htm

      【讨论】:

        猜你喜欢
        • 2014-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-07
        • 2021-05-25
        相关资源
        最近更新 更多