PyQt5スレッドが跨がってオブジェクトを呼び出すにはどのようにするのか
PyQt5では、スレッドをまたいでオブジェクトを呼び出すために、QMetaObject.invokeMethod()メソッドを使用できます。このメソッドは、指定されたオブジェクトのスロット関数を呼び出し、引数を渡すことができます。
PyQt5でスレッド間のクロス呼び出し可能なオブジェクトを実装する方法のサンプルを示します。
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot, QMetaObject
from PyQt5.QtWidgets import QApplication
# 子线程类
class Worker(QThread):
def __init__(self):
super().__init__()
def run(self):
# 模拟耗时操作
self.sleep(5)
# 发送信号通知主线程
self.emitSignal.emit('Hello from worker thread')
# 主线程类
class MainWindow(QObject):
emitSignal = pyqtSignal(str)
def __init__(self):
super().__init__()
@pyqtSlot(str)
def onEmitSignal(self, msg):
print(msg)
def startWorkerThread(self):
self.worker = Worker()
self.worker.emitSignal.connect(self.onEmitSignal)
self.worker.start()
if __name__ == '__main__':
app = QApplication([])
mainWindow = MainWindow()
# 在主线程中调用子线程的槽函数
QMetaObject.invokeMethod(mainWindow, 'startWorkerThread', Qt.QueuedConnection)
app.exec_()
この例では、Worker クラスはサブスレッドを表し、MainWindow クラスはメインスレッドを表します。Worker クラスでは、emitSignal シグナルを使用してメインスレッドにメッセージを送信します。MainWindow クラスでは、onEmitSignal スロット関数を使用してこのメッセージを受信して処理します。
メインスレッドでは、QMetaObject.invokeMethod()メソッドを使用してstartWorkerThreadスロット関数を呼び出し、接続タイプとしてQt.QueuedConnectionを指定して、メインスレッドのイベントループ内からこのスロット関数が呼び出されるようにします。
子スレッドで時間がかかる処理が終わるとemitSignalシグナルが発射され、このシグナルはメインスレッドのonEmitSignalスロット関数に接続されており、スレッド間でクロス呼び出しオブジェクトを実現しています。