我正在尝试创建启动器(例如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
有人知道这可能是什么原因吗?
答案 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()