문제

PYQT 프로그램이 있습니다.이 프로그램에서는 복잡한 이미지를 그리기위한 새로운 스레드를 시작합니다. 스레드가 언제 완료되었는지 알고 싶습니다. 양식에 이미지를 인쇄 할 수 있습니다.

내가 직면 한 유일한 장애물은 GUI 스레드 내부에서 그리기 방법을 호출해야한다는 것입니다. 그래서 GUI 스레드에 드로잉 스레드 내부에서 무언가를하도록 지시하는 방법을 원합니다.

하나의 스레드를 사용하여 할 수 있지만 프로그램은 정지합니다.

나는 마무리를위한 이벤트가있는 배경 작업자를 사용하여 C#에서 그것을했었다.

파이썬에서 그런 일을 할 수있는 방법이 있습니까? 아니면 PYQT 응용 프로그램의 기본 루프를 해킹하고 약간 변경해야합니까?

도움이 되었습니까?

해결책

샘플에서 pyqt-py2.6-gpl-4.4.4-2.exe, Mandelbrot 앱이 있습니다. 설치에서 소스는 C : Python26 lib site-packages pyqt4 examples Threads mandelbrot.pyw에 있습니다. 스레드를 사용하여 PixMap과 신호를 렌더링합니다 (QTCore.signal의 코드 검색)을 gui 스레드에 그릴 시간을 알려줍니다. 당신이 원하는 것 같아요.

다른 팁

프로젝트 중 하나와 비슷한 문제가 있었고 신호를 사용하여 작업자의 결과를 표시하고 진행률 표시 줄을 업데이트 할 때 메인 GUI 스레드를 알려주었습니다.

객체와 신호를 PYQT 참조 안내서. 모두 Python에 적용되는 것은 아닙니다 (이것을 깨닫는 데 시간이 걸렸습니다).

파이썬 신호를 파이썬 함수에 연결하려는 예는 다음과 같습니다.

QtCore.QObject.connect(a, QtCore.SIGNAL("PySig"), pyFunction)
a.emit(QtCore.SIGNAL("pySig"), "Hello", "World")

또한 추가하는 것을 잊지 마십시오 __pyqtSignals__ = ( "PySig", ) 직원 수업에.

다음은 내가 한 일의 제거 버전입니다.

class MyGui(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.worker = None

    def makeWorker(self):
        #create new thread
        self.worker = Worker(work_to_do)
        #connect thread to GUI function
        QtCore.QObject.connect(self.worker, QtCore.SIGNAL('progressUpdated'), self.updateWorkerProgress)
        QtCore.QObject.connect(self.worker, QtCore.SIGNAL('resultsReady'), self.updateResults)
        #start thread
        self.worker.start()

    def updateResults(self):
        results = self.worker.results
        #display results in the GUI

    def updateWorkerProgress(self, msg)
        progress = self.worker.progress
        #update progress bar and display msg in status bar


class Worker(QtCore.QThread):

    __pyqtSignals__ = ( "resultsReady", 
                        "progressUpdated" )

    def __init__(self, work_queue):
        self.progress = 0  
        self.results = []
        self.work_queue = work_queue
        QtCore.QThread.__init__(self, None)

    def run(self):
        #do whatever work
        num_work_items = len(self.work_queue)
        for i, work_item in enumerate(self.work_queue):
            new_progress = int((float(i)/num_work_items)*100)
            #emit signal only if progress has changed
            if self.progress != new_progress:
                self.progress = new_progress
                self.emit(QtCore.SIGNAL("progressUpdated"), 'Working...')
            #process work item and update results
            result = processWorkItem(work_item)
            self.results.append(result)
        self.emit(QtCore.SIGNAL("resultsReady"))

Qapplication.postevent를 사용하여 드로잉 스레드가 메인 스레드로 이벤트를 보낼 수 있다고 생각합니다. 이벤트의 수신기로 객체를 선택하면됩니다. 더 많은 정보

Jeff의 답변에 대한 확장 : the 스레드 지원에 대한 QT 문서 이벤트 처리기 (QT Parlance의 슬롯)가 객체를 "소유하는"스레드에서 실행할 수 있다고 말합니다.

따라서 귀하의 경우 양식에 슬롯 인쇄물 (QIMAGE)과 이미지를 생성하는 모든 것에 대한 도식 (QIMAGE) 신호를 정의하고 대기열 또는 자동 연결을 사용하여 연결합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top