Как показать QMenu, используя глобальное сочетание клавиш в PyQt5? - PullRequest
2 голосов
/ 14 апреля 2020

Я пытался показать экземпляр QMenu с помощью горячей клавиши (например, «F1») с помощью PyQt5 , затем я нашел этот пакет клавиатура .

Попытка использовать его следующим образом: keyboard.add_hotkey('F1', self.show_menu, suppress=True)

Затем я получил следующий код:

import sys

import keyboard

from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__(flags=Qt.WindowStaysOnTopHint)

        self.menu = QMenu('Menu')
        self.menu.addAction(QAction('menu1', self.menu))
        self.menu.addAction(QAction('menu2', self.menu))
        self.menu.addAction(QAction('menu3', self.menu))

        self.show_menu()  # this works well

        keyboard.add_hotkey('F1', self.show_menu, suppress=True)  # this hotkey works but not showing the menu

    def show_menu(self):
        print('111')
        self.menu.popup(QCursor().pos())
        print('222')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    win = MainWindow()
    # win.show()
    sys.exit(app.exec_())

На самом деле, вызов метода self.show_menu в __init__ работает ну, меню может всплыть, как и ожидалось.

Но ВОПРОС заключается в том, что, когда я нажимаю горячую клавишу «F1», «111» и «222» будут напечатаны, но меню , не появится.

Что-то не так, или я могу сделать это другими способами? Пожалуйста, скажите мне, спасибо.

1 Ответ

3 голосов
/ 14 апреля 2020

Обратный вызов, связанный с add_hotkey, выполняется во вторичном потоке, а в коде OP обратным вызовом является метод show_menu, который модифицирует GUI, что запрещено Qt. Решением является использование сигналов:

import sys

import keyboard

from PyQt5.QtCore import Qt, QObject, pyqtSignal
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QAction, QApplication, QMainWindow, QMenu


class KeyBoardManager(QObject):
    F1Signal = pyqtSignal()

    def start(self):
        keyboard.add_hotkey("F1", self.F1Signal.emit, suppress=True)


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__(flags=Qt.WindowStaysOnTopHint)

        self.menu = QMenu("Menu")
        self.menu.addAction(QAction("menu1", self.menu))
        self.menu.addAction(QAction("menu2", self.menu))
        self.menu.addAction(QAction("menu3", self.menu))

        manager = KeyBoardManager(self)
        manager.F1Signal.connect(self.show_menu)
        manager.start()

    def show_menu(self):
        print("111")
        self.menu.popup(QCursor.pos())
        print("222")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    win = MainWindow()
    # win.show()
    sys.exit(app.exec_())
...