2016-06-07 1 views
5

저는 UI의 다양한 컨트롤을 채우는 데 사용되는 API의 일부 데이터를 요청하는 PyQt5를 사용하여 간단한 GUI 응용 프로그램을 만들고 있습니다.모든 작업 또는 여러 특정 작업자를위한 단일 작업 스레드?

PyQt의 작업자 스레드에 관한 예제는 모두 하위 클래스 QThread 인 것처럼 보였고 재정의 된 run() 메서드로 비즈니스 로직을 수행합니다. 이 잘 작동하지만 작업자를 사용하여 다른 시간에 다른 API 호출을 실행하려면.

내 질문은 : 내가하고 싶은 모든 작업에 대해 특정 작업자 스레드를 만들어야하는지, 아니면 다른 시간에 다른 작업을 수행하는 데 사용할 수있는 단일 스레드 클래스를 갖는 방법이 있습니까? 다른 스레드 하위 클래스를 만드는 오버 헤드를 피할 수 있습니까?

+2

'QThread'를 하위 클래스로 분류하면 안됩니다. 대신에,'QtConcurrent :: run'을 사용하거나,'QObject'를 서브 클래스 화하고 이들 작업자 객체를 단일 작업자 스레드로 옮깁니다. –

답변

6

당신이 할 수있는 일은 모든 작업을 수행하는 객체를 디자인하는 것입니다 (슬롯/신호에 대한 QObject를 상속 함). 각 작업이 별도의 기능으로 정의되어 있습니다. 이러한 기능을 슬롯으로 지정할 수 있습니다.

그리고 (사건의 일반적인 순서) :

  • 인스턴스화 QThread 객체입니다.
  • 클래스를 인스턴스화하십시오.
  • YouClass->moveToThread(pThread)을 사용하여 개체를 스레드로 이동하십시오.
  • 이제 각 슬롯에 대한 신호를 정의하고이 신호를 개체의 관련 슬롯에 연결하십시오.
  • 마지막으로 이제 스레드에서 특정 작업을 할 수있는 신호를 방출 할 수 pThread->start()

를 사용하여 스레드를 실행합니다. 하위 클래스 QThread는 QObject에서 파생 된 일반 클래스를 사용할 필요가 없습니다 (슬롯/신호를 사용할 수 있도록).

하나의 스레드에서 하나의 클래스를 사용하여 많은 작업을 수행 할 수 있습니다 (대기열에 저장됩니다). 또는 여러 스레드에서 많은 클래스를 만들 수 있습니다 ("병렬"실행).

내가 여기 예를 시도 할만큼 충분히 파이썬을 모르는

내가하지 않도록 :

주 오 : 당신의 기능을 확장하기를 원한다면 하위 클래스 QThread에 대한 이유가 될 것이다 QThread 클래스 - 특정 스레드 관련 함수를 더 추가합니다. QThread는 스레드를 제어하는 ​​클래스이며 임의/일반 작업을 실행하는 데 사용되지 않습니다 ... 당신이 원할 경우 남용합니다.

+0

훌륭한 답변입니다. 특히 작업이 자동으로 대기열에 들어감을 알 수 있습니다. 어쩌면 나는 그것을위한 예제를 쓸 것이다. – Trilarion

+0

@Trilarion thanks, yes 예를 자유롭게 추가하십시오.) –

3

여기 간결한 예입니다 하나의 실행중인 QThread (시작됨)로 이동되고 신호를 통해 통신하는 작업자 오브젝트 (원하는만큼 많을 수 있음) 또한 스레드가 끝나면 중지됩니다. his answer에 개략적으로 설명 된 code_fodder를 보여줍니다.

from PyQt4 import QtCore 
QtCore.Signal = QtCore.pyqtSignal 

class Master(QtCore.QObject): 

    command = QtCore.Signal(str) 

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

class Worker(QtCore.QObject): 

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

    def do_something(self, text): 
     print('current thread id = {}, message to worker = {}'.format(int(QtCore.QThread.currentThreadId()), text)) 

if __name__ == '__main__': 

    app = QtCore.QCoreApplication([]) 

    # give us a thread and start it 
    thread = QtCore.QThread() 
    thread.start() 

    # create a worker and move it to our extra thread 
    worker = Worker() 
    worker.moveToThread(thread) 

    # create a master object and connect it to the worker 
    master = Master() 
    master.command.connect(worker.do_something) 

    # call a method of the worker directly (will be executed in the actual thread) 
    worker.do_something('wrong way to communicate with worker') 

    # communicate via signals, will execute the method now in the extra thread 
    master.command.emit('right way to communicate with worker') 

    # start the application and kill it after 1 second 
    QtCore.QTimer.singleShot(1000, app.quit) 
    app.exec_() 

    # don't forget to terminate the extra thread 
    thread.quit() 
    thread.wait(5000) 
관련 문제