Skip to content

Commit

Permalink
PR: Ensure QMenu and QToolBar isinstance checks succeed and rem…
Browse files Browse the repository at this point in the history
…ove unneeded wrapper classes (#507)
  • Loading branch information
ccordoba12 authored Dec 16, 2024
2 parents cd0b49b + b938c9d commit 3969d99
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 58 deletions.
28 changes: 2 additions & 26 deletions qtpy/QtGui.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def movePositionPatched(

# Follow similar approach for `QDropEvent` and child classes
QDropEvent.position = lambda self: self.posF()

if PYQT6 or PYSIDE6:
# Part of the fix for https://github.com/spyder-ide/qtpy/issues/394
for _class in (
Expand Down Expand Up @@ -264,27 +265,8 @@ def movePositionPatched(
QDropEvent.posF = lambda self: self.position()


# Make `QAction.setShortcut` and `QAction.setShortcuts` compatible with Qt>=6.4
if PYQT5 or PYSIDE2 or parse(_qt_version) < parse("6.4"):

class _QAction(QAction):
old_set_shortcut = QAction.setShortcut
old_set_shortcuts = QAction.setShortcuts

def setShortcut(self, shortcut):
return set_shortcut(
self,
shortcut,
old_set_shortcut=_QAction.old_set_shortcut,
)

def setShortcuts(self, shortcuts):
return set_shortcuts(
self,
shortcuts,
old_set_shortcuts=_QAction.old_set_shortcuts,
)

# Make `QAction.setShortcut` and `QAction.setShortcuts` compatible with Qt>=6.4
_action_set_shortcut = partialmethod(
set_shortcut,
old_set_shortcut=QAction.setShortcut,
Expand All @@ -295,9 +277,3 @@ def setShortcuts(self, shortcuts):
)
QAction.setShortcut = _action_set_shortcut
QAction.setShortcuts = _action_set_shortcuts
# Despite the two previous lines!
if (
QAction.setShortcut is not _action_set_shortcut
or QAction.setShortcuts is not _action_set_shortcuts
):
QAction = _QAction
50 changes: 18 additions & 32 deletions qtpy/QtWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,21 @@ def __getattr__(name):
elif PYQT6:
from PyQt6 import QtWidgets
from PyQt6.QtGui import (
QAction,
QActionGroup,
QFileSystemModel,
QShortcut,
QUndoCommand,
)
from PyQt6.QtWidgets import *

from qtpy.QtGui import QAction # See spyder-ide/qtpy#461
if parse(_qt_version) < parse("6.4"):
# Make `QAction.setShortcut` and `QAction.setShortcuts` compatible with Qt>=6.4
# See spyder-ide/qtpy#461
from qtpy.QtGui import QAction
else:
from PyQt6.QtGui import QAction

from PyQt6.QtWidgets import *

# Attempt to import QOpenGLWidget, but if that fails,
# don't raise an exception until the name is explicitly accessed.
Expand Down Expand Up @@ -112,9 +119,15 @@ def __getattr__(name):
from PySide2.QtWidgets import *
elif PYSIDE6:
from PySide6.QtGui import QActionGroup, QShortcut, QUndoCommand
from PySide6.QtWidgets import *

from qtpy.QtGui import QAction # See spyder-ide/qtpy#461
if parse(_qt_version) < parse("6.4"):
# Make `QAction.setShortcut` and `QAction.setShortcuts` compatible with Qt>=6.4
# See spyder-ide/qtpy#461
from qtpy.QtGui import QAction
else:
from PySide6.QtGui import QAction

from PySide6.QtWidgets import *

# Attempt to import QOpenGLWidget, but if that fails,
# don't raise an exception until the name is explicitly accessed.
Expand Down Expand Up @@ -211,43 +224,16 @@ def __getattr__(name):
"directory",
)

# Make `addAction` compatible with Qt6 >= 6.4
if PYQT5 or PYSIDE2 or parse(_qt_version) < parse("6.4"):

class _QMenu(QMenu):
old_add_action = QMenu.addAction

def addAction(self, *args):
return add_action(
self,
*args,
old_add_action=_QMenu.old_add_action,
)

# Make `addAction` compatible with Qt6 >= 6.4
_menu_add_action = partialmethod(
add_action,
old_add_action=QMenu.addAction,
)
QMenu.addAction = _menu_add_action
# Despite the previous line!
if QMenu.addAction is not _menu_add_action:
QMenu = _QMenu

class _QToolBar(QToolBar):
old_add_action = QToolBar.addAction

def addAction(self, *args):
return add_action(
self,
*args,
old_add_action=_QToolBar.old_add_action,
)

_toolbar_add_action = partialmethod(
add_action,
old_add_action=QToolBar.addAction,
)
QToolBar.addAction = _toolbar_add_action
# Despite the previous line!
if QToolBar.addAction is not _toolbar_add_action:
QToolBar = _QToolBar
15 changes: 15 additions & 0 deletions qtpy/tests/test_qtwidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ def test_QMenu_functions(qtbot):
QtWidgets.QMenu.exec_(menu.actions(), QtCore.QPoint(1, 1))


def test_QMenu_instance(qtbot):
"""Test `QtWidgets.QMenu` submenus are `QtWidgets.QMenu` instances."""
menu = QtWidgets.QMenu()
menu.addMenu("test")
submenu = menu.children()[1]
assert isinstance(submenu, QtWidgets.QMenu)


@pytest.mark.skipif(
sys.platform == "darwin" and sys.version_info[:2] == (3, 7),
reason="Stalls on macOS CI with Python 3.7",
Expand All @@ -156,6 +164,13 @@ def test_QToolBar_functions(qtbot):
)


def test_QToolBar_instance(qtbot):
"""Test `QtWidgets.QToolBar` passes `isinstance` checks."""
window = QtWidgets.QMainWindow()
new_toolbar = window.addToolBar("Toolbar title")
assert isinstance(new_toolbar, QtWidgets.QToolBar)


@pytest.mark.skipif(
PYQT5 and PYQT_VERSION.startswith("5.9"),
reason="A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.*"
Expand Down

0 comments on commit 3969d99

Please sign in to comment.