2016-08-29 12 views
0

私は、UIコードのブロックとイベントレスポンスを処理するためだけの別のPythonクラスの間に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をまったく使用する必要はありません。信号は、 python呼び出し可能オブジェクトに、スロットとして装飾されているかどうかにかかわらず接続できます。

+0

私はHandlerClassをQObjectのサブクラスにしました。それは美しく動作します。ありがとう! –

+0

これはクロススレッド接続にはいつ必要ですか?常に?これはどこかに書かれていますか? –

+0

@DavidPärssonそれが文書化されているかどうかは分かりませんが、必要な場合は[この回答](http://stackoverflow.com/a/20818401/984421)を参照してください。 – ekhumoro

関連する問題