Поскольку я сейчас портирую приложение с графическим интерфейсом из 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()
...