ApplicationShortcut на QDesktopWidget не работает в PySide2 - PullRequest
0 голосов
/ 08 декабря 2018

Поскольку я сейчас портирую приложение с графическим интерфейсом из Python 2.7.14 / PySide 1.2.4 в Python 3.7.1 / PySide2 5.11.2, я столкнулся с проблемой с механизмом ярлыков.В основном:

  • Установка QShortcuts с контекстом Qt.ApplicationShortcut на QDesktopWidget кажется неработоспособной в PySide2 при хорошей работе в PySide.

Кажется, что другие люди столкнулся с той же проблемой .

  • Является ли это известной ошибкой?
  • Существует ли элегантный обходной путь для размещения ярлыков в приложении где-то в приложении без создания невидимоговиджет для этой цели?

Python 3.7.1 / PySide2 5.11.2 (не работает)


# -*- coding: utf-8 -*-
"""Test application wide shortcut on desktop widget fails in PySide2."""
import logging
from datetime import datetime

from PySide2.QtCore import Qt
from PySide2.QtGui import QKeySequence
from PySide2.QtWidgets import QShortcut, QWidget, QApplication


logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


class Widget(QWidget):
    """Widget with application wide shortcut."""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        shortcut = QShortcut(QKeySequence(Qt.Key_H), QApplication.desktop())
        shortcut.setContext(Qt.ApplicationShortcut)
        shortcut.activated.connect(self.handler)

    def handler(self):
        """Shortcut does not trigger."""
        msg = f"{datetime.now()}"
        logger.info(msg)


# run
app = QApplication()
widget = Widget()
widget.show()
app.exec_()

Python 2.7.14 /PySide 1.2.4 (рабочий)


# -*- coding: utf-8 -*-
"""Test application wide shortcut on desktop widget succeeds in PySide."""
import logging
from datetime import datetime

from PySide.QtCore import Qt
from PySide.QtGui import QKeySequence, QShortcut, QWidget, QApplication


logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


class Widget(QWidget):
    """Widget with application wide shortcut."""

    def __init__(self, *args, **kwargs):
        super(Widget, self).__init__(*args, **kwargs)

        shortcut = QShortcut(QKeySequence(Qt.Key_H), QApplication.desktop())
        shortcut.setContext(Qt.ApplicationShortcut)
        shortcut.activated.connect(self.handler)

    def handler(self):
        """Shortcut does trigger."""
        msg = "{}".format(datetime.now())
        logger.info(msg)


# run
app = QApplication(tuple())
widget = Widget()
widget.show()
app.exec_()

Реальный вариант использования


  • У меня есть ApplicationHotkeyHandler, который являетсяQObject, который определяет все ярлыки приложений.
  • Функции обработчиков в этом экземпляре регистрируются как ярлыки приложений в QDesktopWidget, который входит в состав инфраструктуры Qt и выглядит элегантно и безопасно.способ создания невидимого, искусственного виджета только с цельюудержание ярлыков приложений.

Вот суть того, как это выглядит в приложении:


class ApplicationHotkeyHandler(QObject):
    """Define application wide hotkeys and their handlers here. Shortcuts are
    placed on QDesktopWidget which is an always available part of the Qt
    infrastructure.

    Notes:
        This is a QObject for signals and parenting but not a QWidget
        as we don't have to display anything, so the handler instance cannot 
        serve as parent for QShortcuts.
    """

    @hotkey(QKeySequence(Qt.CTRL + Qt.Key_Q), context=Qt.ApplicationShortcut,)
    def quit(self):
        QApplication.instance().quit()

    ...
...