-
-
Notifications
You must be signed in to change notification settings - Fork 160
Open
Description
In PyQt5, it's common to use a Qt.Key like this:
def _modifierKeyFix(self, e: QKeyEvent, parentFuncName: str):
"""Fix for when keys get stuck in the _keysDown set, call this sparingly."""
current_modifiers = e.modifiers()
for key in MODIFIER_KEYS:
bitcheck = int(current_modifiers & key) # Explicitly convert to int for clarity in logs
if bitcheck == 0 and key in self._keysDown:
RobustRootLogger().debug(f"Inferred Release ({parentFuncName}): {key} Key")
self._keysDown.discard(key)However that fails in PyQt6 even with qtpy, with the following error:
TypeError: unsupported operand type(s) for &: 'KeyboardModifier' and 'Key'
Another example, let's say I want to do similar with Qt.MouseButton:
def _contextMenuRightMouseButtonFix(self, e: QMouseEvent, parentFuncName: str):
"""Fix for when the context menu causes focusloss events that cause the button to get stuck, call this sparingly."""
current_buttons = e.buttons()
# Ensure compatibility with both PyQt5 and PyQt6
if not isinstance(current_buttons, int):
current_buttons = int(current_buttons)
rightbitcheck = int(current_buttons & Qt.RightButton) # Explicitly convert to int for clarity in logs
if rightbitcheck == 0 and Qt.RightButton in self._mouseDown:
RobustRootLogger().debug(f"Inferred Release ({parentFuncName}): Right Button")
self._mouseDown.discard(Qt.RightButton)Raises this error:
"C:\GitHub\PyKotor\Tools\HolocronToolset\src\toolset\gui\widgets\renderer\walkmesh.py", line 886, in _contextMenuRightMouseButtonFix
current_buttons = int(current_buttons)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'MouseButton'
This code works fine:
def _contextMenuRightMouseButtonFix(self, e: QMouseEvent, parentFuncName: str):
"""Fix for when the context menu causes focusloss events that cause the button to get stuck, call this sparingly."""
current_buttons = e.buttons()
right_button_value = Qt.RightButton
if isinstance(current_buttons, Qt.MouseButton):
# PyQt6: current_buttons is a MouseButton enum, use .value to get the int representation
rightbitcheck = current_buttons.value & right_button_value.value
else:
# PyQt5: current_buttons is already an int
rightbitcheck = current_buttons & right_button_value
if rightbitcheck == 0 and Qt.RightButton in self._mouseDown:
RobustRootLogger().debug(f"Inferred Release ({parentFuncName}): Right Button")
self._mouseDown.discard(Qt.RightButton)
An easy way to unify this, imo, is to check API_NAME in ("PyQt6", "PySide6") and if so just slap on the __int__ and __and__ like this in qtpy/QtCore.py:
# Mirror https://github.com/spyder-ide/qtpy/pull/393
if PYQT5 or PYSIDE2:
QLibraryInfo.path = QLibraryInfo.location
QLibraryInfo.LibraryPath = QLibraryInfo.LibraryLocation
if PYQT6 or PYSIDE6:
QLibraryInfo.location = QLibraryInfo.path
QLibraryInfo.LibraryLocation = QLibraryInfo.LibraryPath
QtCore.Qt.MouseButton.__int__ = lambda self: self.value
QtCore.Qt.MouseButton.__and__= lambda self, other: self.value & other
QtCore.Qt.Key.__int__ = lambda self: self.value
QtCore.Qt.Key.__and__= lambda self, other: self.value & other