Issue
I'm trying to create a launcher (like Albert or Spotlight). To do so, I need to connect a shortcut to the show() function of my window. I'm using the keyboard library for this.
This is where I am:
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()
But when calling the shortcut, I'm getting the following Qt error:
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread
Does someone have an idea of what may cause this?
Solution
The message indicates the problem is that the callback is called from another thread and in Qt the GUI can not be updated from another thread, a possible solution is to create a class that provides a signal that connects to the show, and that signal is issued as a callback.
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()
Or a better option for these cases use QMetaObject::invokeMethod()
with Qt::QueuedConnection
since show()
is a slot as I show below:
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()
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.