aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2022-08-25 11:54:56 +0200
committerChristian Tismer <tismer@stackless.com>2022-09-02 12:15:29 +0200
commit042413450f6b6e95241c2b6bcad7917173fd26ce (patch)
tree5ed511bff410cda4c867d66c19877d16ac44fa46
parent1249a264d86d6c91421938a3a5dd66d4d9ebeb8d (diff)
PyEnum: Improve the handling of QKeyCombination
After turning IntEnum into Enum, a few classes need more attention because the simple int coercion is no more sufficient. Instead, a bit of help is necessary to make the usage of the __or__ operator consistent, again. On first sight, this coercion to KeyCombination looks slightly unpythonic. But this originates in the complex matters. If you observe what types are actually added, this is very correct. Using the IntEnum version instead is not better. It is just hiding the ongoings by using int, which would also allow to combine two characters as a bad side effect. [ChangeLog][PySide6] PyEnum now handles QKeyCombination correctly with "|" or (deprecated) "+" operators, without falling back to using IntEnum. Task-number: PYSIDE-1735 Change-Id: I08b93b8b7ece75ca650f2916ec6f6f5bb711a70b Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 20729eb6ffda8771c192e1614f8e53823108cab1) Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml17
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp8
-rw-r--r--sources/pyside6/PySide6/support/deprecated.py30
-rw-r--r--sources/pyside6/tests/pysidetest/qvariant_test.py15
4 files changed, 66 insertions, 4 deletions
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
index 2942e3d38..6f6484cbf 100644
--- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
@@ -328,7 +328,20 @@
</conversion-rule>
</primitive-type>
- <value-type name="QKeyCombination"/>
+ <value-type name="QKeyCombination">
+ <!-- The following do-nothing function is needed for coercion of constructs like
+ QKeyCombination(Qt.CTRL | Qt.Key_B)
+ -->
+ <add-function signature="QKeyCombination(QKeyCombination)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="keycombination-from-keycombination"/>
+ </add-function>
+ <!-- This is just a copy of KeyModifier to handle Modifier the same -->
+ <add-function signature="QKeyCombination(Qt::Modifier @modifiers@, Qt::Key @key@)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="keycombination-from-modifier"/>
+ </add-function>
+ </value-type>
<value-type name="QMetaType">
<enum-type name="Type" python-type="IntEnum"/>
@@ -578,7 +591,7 @@
<enum-type name="LayoutDirection"/>
<enum-type name="MaskMode"/>
<enum-type name="MatchFlag" flags="MatchFlags"/>
- <enum-type name="Modifier"/>
+ <enum-type name="Modifier" python-type="Flag"/>
<enum-type name="MouseButton" flags="MouseButtons"/>
<enum-type name="MouseEventFlag" flags="MouseEventFlags" since="5.3"/>
<enum-type name="MouseEventSource" since="5.3"/>
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
index b0af6c354..a1ab063af 100644
--- a/sources/pyside6/PySide6/glue/qtcore.cpp
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -1628,3 +1628,11 @@ if (Shiboken::Enum::check(%PYARG_0)) {
pythonToCpp(pyResult, &cppResult);
}
// @snippet qabstractitemmodel_data
+
+// @snippet keycombination-from-keycombination
+cptr = new ::%TYPE(%1);
+// @snippet keycombination-from-keycombination
+
+// @snippet keycombination-from-modifier
+cptr = new ::%TYPE(%1, %2);
+// @snippet keycombination-from-modifier
diff --git a/sources/pyside6/PySide6/support/deprecated.py b/sources/pyside6/PySide6/support/deprecated.py
index cd620eb05..a0df14715 100644
--- a/sources/pyside6/PySide6/support/deprecated.py
+++ b/sources/pyside6/PySide6/support/deprecated.py
@@ -50,6 +50,9 @@ Functions that are to be called for
Note that this fixing code is run after all initializations, but before the
import is finished. But that is no problem since the module is passed in.
+
+PYSIDE-1735: This is also used now for missing other functions (overwriting __or__
+ in Qt.(Keyboard)Modifier).
"""
import warnings
@@ -75,4 +78,31 @@ def _unused_fix_for_QtGui(QtGui):
if name.startswith("QMatrix") and "data" in cls.__dict__:
cls.constData = constData
+# PYSIDE-1735: Fix for a special enum function
+def fix_for_QtCore(QtCore):
+ from enum import Flag
+ Qt = QtCore.Qt
+ flag_or = Flag.__or__
+
+ def func_or(self, other):
+ if isinstance(self, Flag) and isinstance(other, Flag):
+ # this is normal or-ing flags together
+ return Qt.KeyboardModifier(self.value | other.value)
+ return QtCore.QKeyCombination(self, other)
+
+ def func_add(self, other):
+ warnings.warn(dedent(f"""
+ The "+" operator is deprecated in Qt For Python 6.0 .
+ Please use "|" instead."""), PySideDeprecationWarningRemovedInQt6, stacklevel=2)
+ return func_or(self, other)
+
+ Qt.KeyboardModifier.__or__ = func_or
+ Qt.KeyboardModifier.__ror__ = func_or
+ Qt.Modifier.__or__ = func_or
+ Qt.Modifier.__ror__ = func_or
+ Qt.KeyboardModifier.__add__ = func_add
+ Qt.KeyboardModifier.__radd__ = func_add
+ Qt.Modifier.__add__ = func_add
+ Qt.Modifier.__radd__ = func_add
+
# eof
diff --git a/sources/pyside6/tests/pysidetest/qvariant_test.py b/sources/pyside6/tests/pysidetest/qvariant_test.py
index c3d2614df..e6977082e 100644
--- a/sources/pyside6/tests/pysidetest/qvariant_test.py
+++ b/sources/pyside6/tests/pysidetest/qvariant_test.py
@@ -36,8 +36,8 @@ from init_paths import init_test_paths
init_test_paths(True)
from testbinding import TestObject
-from PySide6.QtCore import Qt
-from PySide6.QtGui import QKeySequence
+from PySide6.QtCore import Qt, QKeyCombination
+from PySide6.QtGui import QKeySequence, QAction
from helper.usesqapplication import UsesQApplication
@@ -49,6 +49,17 @@ class QVariantTest(UsesQApplication):
ks = QKeySequence(Qt.ShiftModifier, Qt.ControlModifier, Qt.Key_P, Qt.Key_R)
self.assertEqual(TestObject.checkType(ks), 4107)
+ # PYSIDE-1735: Test the new way to address QKeyCombination after moving IntEnum to Enum
+ @unittest.skipUnless(sys.pyside63_option_python_enum, "only implemented for new enums")
+ def testQKeySequenceMoreVariations(self):
+ QAction().setShortcut(Qt.CTRL | Qt.Key_B)
+ QAction().setShortcut(Qt.CTRL | Qt.ALT | Qt.Key_B)
+ QAction().setShortcut(Qt.CTRL | Qt.AltModifier | Qt.Key_B)
+ QAction().setShortcut(QKeySequence(QKeyCombination(Qt.CTRL | Qt.Key_B)))
+ QKeySequence(Qt.CTRL | Qt.Key_Q)
+ # Issues a warning but works as well
+ QKeySequence(Qt.CTRL + Qt.Key_Q)
+
if __name__ == '__main__':
unittest.main()