【发布时间】:2021-01-14 18:51:10
【问题描述】:
我正在创建一个启动器,样式为Albert、Alfred 或uLauncher。我的应用程序在后台运行,并在按下热键时显示。我使用pynput 来收听热键。我不能使用 PyQt5 热键的功能(不能吗?),因为我需要在系统范围内监听键盘事件,而不仅仅是应用程序范围内。
按下快捷方式时,它会调用我的小部件的 show() 方法。唯一的问题是,尽管使用了 raise_、setFocus 和 activateWindow,但我无法将焦点重新放在窗口上。
我发现了一个(丑陋的)解决方法,它包括打开一个 QMessageBox(+ 调整它的外观使其不可见,但我没有把它放在示例代码中)然后立即关闭它。
当我在 Linux 上工作时,这种变通方法正在发挥作用,我已经准备好忘记它是多么丑陋,因为它完成了这项工作。但我切换到 Windows(我的应用程序也必须在其上运行),现在这个厚颜无耻的把戏似乎会导致我的应用程序冻结然后崩溃。业力?肯定的。
无论如何,如果我的应用程序无法获得焦点,我的应用程序将毫无用处,所以我要问两个问题,如果只解决一个问题,我会很高兴。 :)
- 你知道为什么显示 QMessageBox 会导致崩溃吗?
- 您知道其他方法可以让我的应用程序重新获得关注吗?
这是一个可以使用的示例代码。
非常感谢:)
编辑:我刚刚发现,即使停用 QMessageBox 解决方法,应用程序最终也会崩溃(在调用 5、20、30 次热键之后)。所以问题也可能在于我将快捷方式绑定到 GUI 的方式,我担心线程问题,但这超出了我的知识范围:/
import sys
from PyQt5.QtWidgets import QLineEdit, QApplication, QMessageBox
from PyQt5.QtCore import QSize, Qt, QEvent
from pynput import keyboard
class Launcher(QLineEdit):
def __init__(self):
super().__init__()
self.setFixedSize(QSize(600, 50))
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setPlaceholderText('Search...')
self.installEventFilter(self)
self.set_shortcut('<ctrl>+`')
def set_shortcut(self, shortcut):
def for_canonical(f):
return lambda k: f(listener.canonical(k))
hotkey = keyboard.HotKey(
keyboard.HotKey.parse(shortcut),
self.wake_up)
listener = keyboard.Listener(
on_press=for_canonical(hotkey.press),
on_release=for_canonical(hotkey.release))
listener.start()
def wake_up(self):
print('Waking up')
self.show()
self.cheeky_focus_stealer()
def cheeky_focus_stealer(self):
self.setFocus()
self.raise_()
self.activateWindow()
# Working of linux, but causes freeze/crash on Windows 10
message_box = QMessageBox(self)
message_box.show()
message_box.hide()
def eventFilter(self, obj, event):
if obj is self and event.type() == QEvent.KeyPress:
if event.key() == Qt.Key_Escape:
self.hide()
return True
return super().eventFilter(obj, event)
def main():
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
window = Launcher()
window.show()
app.exec_()
if __name__ == "__main__":
main()
【问题讨论】: