In PySide I can get the dictionary with possible/allowed enumerator values and their string representations by using values
attribute. For example:
QtWidgets.QMessageBox.StandardButton.values.items()
. How to achieve the same in PyQt4/PyQt5? Is that even possible? I have found nothing about this in the docs.
PySide/PySide2 have a built-in enum type (Shiboken.EnumType
) which supports iteration over the names/values. It also supports a name
attribute, which you can use to get the enumerator name directly from its value.
Unfortunately, all versions of PyQt earlier than PyQt6 do not provide similar support. PyQt6 enums are subclasses of Python's IntEnum (so do support the above features), but PyQt5 enums are just plain subclasses of int
with no additional features. This means you will have to roll your own solution to work around this limitation. It's tempting to try to use the Meta-Object System for this, but many classes (such as the Qt
namespace) don't provide access to the necessary staticMetaObject
, so that approach could never lead to a workable solution.
A much simpler and more general solution would be to leverage Python's introspection support. This will require obtaining a reference to the namespace object where the enumeration is defined, so that its __dict__
can be searched for all the relevant enumerators. In general, this namespace object won't always be available locally, and its parent module very often won't even have been imported yet, but importlib can be used to resolve this issue efficiently. In addition, some namespaces are multi-level (e.g. QtGui.QTouchEvent.TouchPoint.InfoFlag
), so that needs special handling as well.
A basic implementation might therefore look something like this:
from importlib import import_module
def enum_mapping(enum):
ns = import_module(enum.__module__)
for name in enum.__qualname__.split('.')[:-1]:
ns = getattr(ns, name)
mapping = {}
for key, value in ns.__dict__.items():
if isinstance(value, enum):
mapping[key] = value
return mapping
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
for enum in (
QTouchEvent.TouchPoint.InfoFlag,
QTableWidget.EditTrigger,
QMessageBox.StandardButton,
):
print(f'{enum.__qualname__}:')
for key, value in enum_mapping(enum).items():
print(f' {key} = {value}')
print()
Output:
QTouchEvent.TouchPoint.InfoFlag:
Pen = 1
Token = 2
QAbstractItemView.EditTrigger:
AllEditTriggers = 31
AnyKeyPressed = 16
CurrentChanged = 1
DoubleClicked = 2
EditKeyPressed = 8
NoEditTriggers = 0
SelectedClicked = 4
QMessageBox.StandardButton:
Abort = 262144
Apply = 33554432
ButtonMask = -769
Cancel = 4194304
Close = 2097152
Default = 256
Discard = 8388608
Escape = 512
FirstButton = 1024
FlagMask = 768
Help = 16777216
Ignore = 1048576
LastButton = 134217728
No = 65536
NoAll = 131072
NoButton = 0
NoToAll = 131072
Ok = 1024
Open = 8192
Reset = 67108864
RestoreDefaults = 134217728
Retry = 524288
Save = 2048
SaveAll = 4096
Yes = 16384
YesAll = 32768
YesToAll = 32768