尝试显示小部件时出现线程问题

时间:2018-10-18 18:11:29

标签: python python-2.7 pyside

我正在尝试创建启动器(例如Albert或Spotlight)。为此,我需要将快捷方式连接到窗口的show()函数。我正在为此使用 keyboard 库。

这就是我所在的地方

import sys
from PySide import QtGui
import keyboard


class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Example')

def main():
    app = QtGui.QApplication(sys.argv)

    window = Example()
    keyboard.add_hotkey('ctrl+alt+9', window.show, args=[])

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

但是在调用快捷方式时,出现以下Qt错误:

QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread

有人知道这可能是什么原因吗?

1 个答案:

答案 0 :(得分:1)

该消息表明问题是回调是从另一个线程调用的,并且在Qt中无法从另一个线程更新GUI,一种可能的解决方案是创建一个类,该类提供连接到节目的信号,并且信号作为回调发出。

import sys
import keyboard
from PySide import QtCore, QtGui


class SignalHelper(QtCore.QObject):
    signal = QtCore.Signal()


class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Example')


def main():
    app = QtGui.QApplication(sys.argv)
    window = Example()
    helper = SignalHelper()
    helper.signal.connect(window.show)
    keyboard.add_hotkey('ctrl+alt+9', helper.signal.emit)
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

对于这些情况,更好的选择是将QMetaObject::invokeMethod()Qt::QueuedConnection一起使用,因为show()是一个插槽,如下所示:

import sys
import keyboard
from PySide import QtCore, QtGui


class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Example')


def main():
    app = QtGui.QApplication(sys.argv)
    window = Example()
    keyboard.add_hotkey('ctrl+alt+9', 
        QtCore.QMetaObject.invokeMethod, 
        args=(window, "show", QtCore.Qt.QueuedConnection))
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()