2015-04-14 2 views
0

Я действительно пытаюсь закончить писать графическое приложение, которое требует нескольких разных потоков. На высоком уровне мне требуется:Как передать переменную QThread (PySide или PyQT)

Речь GUI, в которой есть кнопка для открытия браузера каталога, который пользователь выбирает для каталога. При выборе каталога начинается поток, который ищет определенный тип файла. Это может занять много времени, поэтому я знаю, что мне нужно добавить отдельный QThread.

После того, как поток BrowseFile завершил поиск файлов, он возвращает файлList, который затем перебирается в файлы subListList. Каждый файл 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_()) 

Есть ли лучший способ пройти путь к каталогу в browseThread, чем при использовании * арга, ** кВт?

Как вернуть файл списка обратно в основной поток, который затем я могу передать нескольким новым потокам обработки.

Я уверен, что делая это тяжелее, чем это должно быть так, надеюсь, кто-то может помочь мне

благодаря

ответ

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

Хорошая точка в том, что вы можете использовать рабочий с или без резьбы, и вы можете легко передать параметры рабочего с помощью сеттеров.

Чтобы узнать больше о сигналах и слотах Qt для потоков Я предлагаю вам прочитать:

0

Вы должны быть в состоянии использовать механизм сигналов и слотов Qt.

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

Вы также можете использовать попутную систему обмена сообщениями.

Нет ничего плохого в передаче его в качестве аргумента. Просто убедитесь, что вы делаете это безопасно: http://effbot.org/zone/thread-synchronization.htm

Смежные вопросы