How to connect functions to PyQt signals outside of main thread
我正在创建一个 PyQt 应用程序,我希望有一个后台线程来连接一些事件处理程序,然后永远循环直到主窗口关闭。我遇到的问题是,我连接的事件处理程序只有在它们是我的 MainWindow 类中定义的函数时才起作用。我在下面创建了一个最小的复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
import threading
from PyQt5. QtWidgets import QApplication , QDialog , QPushButton , QVBoxLayout
class MainWindow(QDialog): def __init__(self): super(MainWindow, self).__init__()
self.button1 = QPushButton("Click Me", self) self.button2 = QPushButton("Me Too!", self)
layout = QVBoxLayout() layout.addWidget(self.button1) layout.addWidget(self.button2) self.setLayout(layout)
def test(self): print("test inside class")
def test2(): print("test outside class")
def main(window): window.button1.clicked.connect(window.test) window.button2.clicked.connect(test2) # Loop that runs in thread…
app = QApplication([]) window = MainWindow() window.show() threading.Thread(target=main, args=[window]).start() app.exec_() |
当我运行此代码时,第一个按钮按预期向控制台打印一条消息,但第二个按钮在单击时什么也不做。如果我在主线程中运行 main(window) 函数,那么两个按钮都可以工作。我知道,在我的小示例程序中,这将是显而易见的解决方案,但出于复杂的原因,我需要能够从我的应用程序的后台线程连接事件处理程序。为什么当我在主线程之外连接像 test2() 这样在 MainWindow 类之外定义的函数时不起作用?
我仍在找出问题的原因,但解决方案是指出连接的类型,在这种情况下 Qt::DirectConnection 将使函数 test2 在发出信号的对象的同一线程上运行(发出信号的对象是位于主线程中的按钮)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
import threading
from PyQt5 import QtCore , QtWidgets
class MainWindow(QtWidgets.QDialog): def __init__(self): super(MainWindow, self).__init__() self.button1 = QtWidgets.QPushButton("Click Me") self.button2 = QtWidgets.QPushButton("Me Too!") layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.button1) layout.addWidget(self.button2)
@QtCore.pyqtSlot() def test(self): print("test inside class")
def test2(): print("test outside class")
def main(window): window.button1.clicked.connect(window.test) window.button2.clicked.connect(test2, QtCore.Qt.DirectConnection) while True: QtCore.QThread.sleep(1)
if __name__ == ‘__main__’: import sys app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() threading.Thread(target=main, args=(window,), daemon=True).start() sys.exit(app.exec_()) |
- 谢谢,使用 Qt.DirectConnection 解决了这个问题。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/python/268008.html