2017-10-02 6 views
1

qthreadからqthreadへのシグナルの送信に問題があります。私が使っているコードの同様の抽出物は、以下の通りです:Pythonが2つのQThreads間でシグナルを送信しています

class auth(QtCore.QThread): 
    authenticate = pyqtSignal() 
    serverDown = pyqtSignal() 
    accntonline = pyqtSignal() 

    def __init__(self, parent=None): 
     super(auth, self).__init__(parent) 
    def run(self): 
     self.authenticate.emit() 

class Threadclass(QtCore.QThread): 
    authenticator = "n" 
    def __init__(self, parent=None): 

     super(Threadclass, self).__init__(parent) 
     #setting first values avoiding errors 

     self.a = auth(self) 

     self.a.authenticate.connect(self.setauthentication) 

    #All small functions setting values from box. 

    def setauthentication(self): 
     print("awdawdawda") 
     self.authenticator = "y" 

私は変更されません変数self.authenticator AUTHのスレッドを実行すると。それは "n"のままです。 すべてのヘルプは、あなたがQThreadrunメソッドをオーバーライドする場合は、明示的にそのexecメソッドを呼び出さない限り、それは独自のイベントループを開始しません

+0

あなたは 'QThread'の' run'メソッドをオーバーライドする場合、それはあなたがない限り、独自のイベントループを開始しません明示的に 'exec'メソッドを呼び出します。イベントループは、スレッド間信号の処理に必要です。このため、通常は、 'run'をオーバーライドするのではなく、ワーカーオブジェクトを作成してスレッドに移動する方が良いでしょう。 – ekhumoro

+0

@ekhumoro有用な情報私が与えたコードを使用して例を提供できるかどうかは可能ですか? – Kermit

+0

サンプルコードに基づいて回答を追加しました。うまくいけば、実際のアプリケーションで使用するためにそれをどのように適応させるかを見ることができます。 – ekhumoro

答えて

1

を高く評価しました。イベントループは、スレッド間信号の処理に必要です。このため、runをオーバーライドするのではなく、ワーカーオブジェクトを作成してスレッドに移動する方が一般的に適しています。ここで

は、スレッドとワーカーオブジェクトを使用する方法を示しデモスクリプトです:

import sys 
from PyQt5 import QtWidgets, QtCore 

class AuthWorker(QtCore.QObject): 
    authenticate = QtCore.pyqtSignal() 

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

    def run(self): 
     QtCore.QThread.sleep(0.5) 
     self.authenticate.emit() 

class Worker(QtCore.QObject): 
    finished = QtCore.pyqtSignal(str) 
    authenticator = "n" 

    def __init__(self, parent=None): 
     super(Worker, self).__init__(parent) 
     self.auth = AuthWorker() 
     self.auth_thread = QtCore.QThread() 
     self.auth.moveToThread(self.auth_thread) 
     self.auth.authenticate.connect(self.setauthentication) 
     self.auth_thread.started.connect(self.auth.run) 

    def setauthentication(self): 
     self.authenticator = "y" 

    def run(self): 
     self.auth_thread.start() 
     QtCore.QThread.sleep(1) 
     self.finished.emit('auth: %s' % self.authenticator) 

class Window(QtWidgets.QWidget): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.button = QtWidgets.QPushButton('Test', self) 
     self.button.clicked.connect(self.handleButton) 
     self.edit = QtWidgets.QLineEdit(self) 
     self.edit.setReadOnly(True) 
     layout = QtWidgets.QVBoxLayout(self) 
     layout.addWidget(self.edit) 
     layout.addWidget(self.button) 
     self.thread = QtCore.QThread() 
     self.worker = Worker() 
     self.worker.moveToThread(self.thread) 
     self.worker.finished.connect(self.handleFinished) 
     self.thread.started.connect(self.worker.run) 

    def handleFinished(self, text): 
     self.thread.quit() 
     self.edit.setText(text) 

    def handleButton(self): 
     if not self.thread.isRunning(): 
      self.edit.clear() 
      self.thread.start() 

if __name__ == '__main__': 

    app = QtWidgets.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(600, 100, 200, 100) 
    window.show() 
    sys.exit(app.exec_()) 
+0

これはほとんど問題を解決すると思いますが、別のウィンドウ(ボタン押下信号がスレッドを呼び出すGUI)からこれらのスレッドを呼び出すにはどうすればいいですか? – Kermit

+0

@Kermit。私はスレッドと単純なguiとの間の通信を示すコード例を展開しました。 – ekhumoro

関連する問題