2016-08-29 2 views
0

저는 UI 코드 블록과 이벤트 응답을 처리하기위한 별도의 파이썬 클래스 사이에 pyqt 신호를 설정하려고합니다. UI 코드에 핸들러 (고전적인 MVC 스타일)에 대한 액세스 권한을 부여하고 싶지 않습니다. 불행하게도 슬롯을 신호에 연결하는 데 문제가 있습니다. 다음은 코드입니다.PyQt5 슬롯을 클래스의 신호 함수에 어떻게 연결합니까?

from PyQt5 import QtCore 
from PyQt5.QtCore import QObject 

class UiClass(QObject): 
    mySignal = QtCore.pyqtSignal(str) 
    def __init__(self): 
     QObject.__init__(self) 
    def send_signal(self): 
     self.mySignal.emit("Hello world!") 

class HandlerClass(): 
    currentMessage = "none" 
    def register(self, mySignal): 
     mySignal.connect(self.receive_signal)   
    @QtCore.pyqtSlot(str) 
    def receive_signal(self, message): 
     self.currentMessage = message 
     print(message) 

ui = UiClass() 
handler = HandlerClass() 
handler.register(ui.mySignal) 
ui.send_signal() 

이 코드를 실행할 때 handler.register 줄에서 실패합니다. 여기에 오류가 있습니다 :

Traceback (most recent call last):

File "C:\git\IonControl\testpyqtslot.py", line 25, in

handler.register(ui.mySignal)

File "C:\git\IonControl\testpyqtslot.py", line 17, in register

mySignal.connect(self.receive_signal)

TypeError: connect() failed between UiClass.mySignal[str] and receive_signal()

이 코드가 성공적으로 슬롯에 신호를 등록하고 끝에 "hello world"라는 문자를 인쇄하도록합니다. 여기서 내가 뭘 잘못 했니?

기본적인 질문은 이것입니다 : 어떻게 신호를 클래스의 일부인 슬롯 함수에 연결합니까?

답변

3

QObject에서 상속받지 않는 클래스에 pyqtSlot 데코레이터를 사용하기 때문에 오류가 발생합니다. 데코레이터를 없애거나 HandlerClass 서브 클래스를 QObject으로 만들어 문제를 해결할 수 있습니다.

pyqtSlot의 주된 목적은 각각 다른 서명으로 슬롯의 여러 가지 서로 다른 오버로드를 정의하는 것입니다. 크로스 스레드 연결을 만들 때 가끔 필요할 수도 있습니다. 그러나 이러한 유스 케이스는 비교적 드물며 대부분의 PyQt 애플리케이션에서는 pyqtSlot을 전혀 사용할 필요가 없습니다. 신호는 파이썬 호출 가능 객체에 연결할 수 있습니다.이 객체는 슬롯으로 꾸며 졌든 그렇지 않든 상관 없습니다.

+0

나는 HandlerClass를 QObject의 하위 클래스로 만들었으며 아름답게 작동합니다. 감사! –

+0

크로스 스레드 연결에는 언제 이것이 필요합니까? 항상? 이것이 어딘가에 기록되어 있습니까? –

+0

@ DavidPärsson. 그것이 문서화되어 있는지는 모르지만, 필요할 수도있는 시나리오에 대해서는 [이 대답] (http://stackoverflow.com/a/20818401/984421)을 참조하십시오. – ekhumoro

관련 문제