Skip to content

Commit deccf20

Browse files
authored
[pyqgis] add method to retrieve metaEnum from an enum value or type (#7023)
1 parent ae89b4f commit deccf20

File tree

6 files changed

+130
-33
lines changed

6 files changed

+130
-33
lines changed

python/core/__init__.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
from .additions.edit import edit, QgsEditError
3030
from .additions.fromfunction import fromFunction
31+
from .additions.metaenum import metaEnumFromType, metaEnumFromValue
3132
from .additions.processing import processing_output_layer_repr, processing_source_repr
3233
from .additions.projectdirtyblocker import ProjectDirtyBlocker
3334
from .additions.qgsdefaultvalue import _isValid
@@ -52,25 +53,25 @@
5253
# -----------------
5354
# DO NOT EDIT BELOW
5455
# These are automatically added by calling sipify.pl script
55-
QgsTolerance.UnitType.parentClass = lambda: QgsTolerance
56-
QgsAuthManager.MessageLevel.parentClass = lambda: QgsAuthManager
57-
QgsDataItem.Type.parentClass = lambda: QgsDataItem
58-
QgsDataItem.State.parentClass = lambda: QgsDataItem
59-
QgsLayerItem.LayerType.parentClass = lambda: QgsLayerItem
60-
QgsDataProvider.DataCapability.parentClass = lambda: QgsDataProvider
61-
QgsDataSourceUri.SslMode.parentClass = lambda: QgsDataSourceUri
62-
QgsNetworkContentFetcherRegistry.FetchingMode.parentClass = lambda: QgsNetworkContentFetcherRegistry
63-
QgsSnappingConfig.SnappingMode.parentClass = lambda: QgsSnappingConfig
64-
QgsSnappingConfig.SnappingType.parentClass = lambda: QgsSnappingConfig
65-
QgsUnitTypes.DistanceUnit.parentClass = lambda: QgsUnitTypes
66-
QgsUnitTypes.AreaUnit.parentClass = lambda: QgsUnitTypes
67-
QgsUnitTypes.AngleUnit.parentClass = lambda: QgsUnitTypes
68-
QgsUnitTypes.RenderUnit.parentClass = lambda: QgsUnitTypes
69-
QgsUnitTypes.LayoutUnit.parentClass = lambda: QgsUnitTypes
70-
QgsVectorSimplifyMethod.SimplifyHint.parentClass = lambda: QgsVectorSimplifyMethod
71-
QgsVectorSimplifyMethod.SimplifyAlgorithm.parentClass = lambda: QgsVectorSimplifyMethod
72-
QgsRasterProjector.Precision.parentClass = lambda: QgsRasterProjector
73-
QgsAbstractGeometry.SegmentationToleranceType.parentClass = lambda: QgsAbstractGeometry
74-
QgsGeometry.BufferSide.parentClass = lambda: QgsGeometry
75-
QgsGeometry.EndCapStyle.parentClass = lambda: QgsGeometry
76-
QgsGeometry.JoinStyle.parentClass = lambda: QgsGeometry
56+
QgsTolerance.UnitType.baseClass = QgsTolerance
57+
QgsAuthManager.MessageLevel.baseClass = QgsAuthManager
58+
QgsDataItem.Type.baseClass = QgsDataItem
59+
QgsDataItem.State.baseClass = QgsDataItem
60+
QgsLayerItem.LayerType.baseClass = QgsLayerItem
61+
QgsDataProvider.DataCapability.baseClass = QgsDataProvider
62+
QgsDataSourceUri.SslMode.baseClass = QgsDataSourceUri
63+
QgsNetworkContentFetcherRegistry.FetchingMode.baseClass = QgsNetworkContentFetcherRegistry
64+
QgsSnappingConfig.SnappingMode.baseClass = QgsSnappingConfig
65+
QgsSnappingConfig.SnappingType.baseClass = QgsSnappingConfig
66+
QgsUnitTypes.DistanceUnit.baseClass = QgsUnitTypes
67+
QgsUnitTypes.AreaUnit.baseClass = QgsUnitTypes
68+
QgsUnitTypes.AngleUnit.baseClass = QgsUnitTypes
69+
QgsUnitTypes.RenderUnit.baseClass = QgsUnitTypes
70+
QgsUnitTypes.LayoutUnit.baseClass = QgsUnitTypes
71+
QgsVectorSimplifyMethod.SimplifyHint.baseClass = QgsVectorSimplifyMethod
72+
QgsVectorSimplifyMethod.SimplifyAlgorithm.baseClass = QgsVectorSimplifyMethod
73+
QgsRasterProjector.Precision.baseClass = QgsRasterProjector
74+
QgsAbstractGeometry.SegmentationToleranceType.baseClass = QgsAbstractGeometry
75+
QgsGeometry.BufferSide.baseClass = QgsGeometry
76+
QgsGeometry.EndCapStyle.baseClass = QgsGeometry
77+
QgsGeometry.JoinStyle.baseClass = QgsGeometry

python/core/additions/metaenum.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
metaenum.py
6+
---------------------
7+
Date : May 2018
8+
Copyright : (C) 2018 by Denis Rouzaud
9+
Email : denis@opengis.ch
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
21+
def metaEnumFromValue(enumValue, raiseException=True, baseClass=None):
22+
return metaEnumFromType(enumValue.__class__, raiseException, baseClass)
23+
24+
25+
def metaEnumFromType(enumClass, raiseException=True, baseClass=None):
26+
if enumClass == int:
27+
if raiseException:
28+
raise TypeError("enumClass is an int, while it should be an enum")
29+
else:
30+
return None
31+
32+
if baseClass is None:
33+
try:
34+
baseClass = enumClass.baseClass
35+
return metaEnumFromType(enumClass, raiseException, baseClass)
36+
except AttributeError:
37+
if raiseException:
38+
raise ValueError("Enum type does not implement baseClass method. Provide the base class as argument.")
39+
40+
try:
41+
idx = baseClass.staticMetaObject.indexOfEnumerator(enumClass.__name__)
42+
meta_enum = baseClass.staticMetaObject.enumerator(idx)
43+
except AttributeError:
44+
if raiseException:
45+
raise TypeError("could not get the metaEnum for {}".format(enumClass.__name__))
46+
meta_enum = None
47+
48+
return meta_enum

python/gui/__init__.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@
2929
# -----------------
3030
# DO NOT EDIT BELOW
3131
# These are automatically added by calling sipify.pl script
32-
QgsAuthSettingsWidget.WarningType.parentClass = lambda: QgsAuthSettingsWidget
33-
QgsColorButton.Behavior.parentClass = lambda: QgsColorButton
34-
QgsColorTextWidget.ColorTextFormat.parentClass = lambda: QgsColorTextWidget
35-
QgsFilterLineEdit.ClearMode.parentClass = lambda: QgsFilterLineEdit
36-
QgsFloatingWidget.AnchorPoint.parentClass = lambda: QgsFloatingWidget
37-
QgsFontButton.Mode.parentClass = lambda: QgsFontButton
38-
QgsMapToolIdentify.IdentifyMode.parentClass = lambda: QgsMapToolIdentify
39-
QgsAttributeTableFilterModel.FilterMode.parentClass = lambda: QgsAttributeTableFilterModel
40-
QgsAttributeTableFilterModel.ColumnType.parentClass = lambda: QgsAttributeTableFilterModel
41-
QgsDualView.ViewMode.parentClass = lambda: QgsDualView
32+
QgsAuthSettingsWidget.WarningType.baseClass = QgsAuthSettingsWidget
33+
QgsColorButton.Behavior.baseClass = QgsColorButton
34+
QgsColorTextWidget.ColorTextFormat.baseClass = QgsColorTextWidget
35+
QgsFilterLineEdit.ClearMode.baseClass = QgsFilterLineEdit
36+
QgsFloatingWidget.AnchorPoint.baseClass = QgsFloatingWidget
37+
QgsFontButton.Mode.baseClass = QgsFontButton
38+
QgsMapToolIdentify.IdentifyMode.baseClass = QgsMapToolIdentify
39+
QgsAttributeTableFilterModel.FilterMode.baseClass = QgsAttributeTableFilterModel
40+
QgsAttributeTableFilterModel.ColumnType.baseClass = QgsAttributeTableFilterModel
41+
QgsDualView.ViewMode.baseClass = QgsDualView

scripts/sipify.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ sub detect_non_method_member{
614614
}
615615
if ($LINE =~ m/Q_ENUM\(\s*(\w+)\s*\)/ ){
616616
if ($LINE !~ m/SIP_SKIP/){
617-
my $enum_helper = "$ACTUAL_CLASS.$1.parentClass = lambda: $ACTUAL_CLASS";
617+
my $enum_helper = "$ACTUAL_CLASS.$1.baseClass = $ACTUAL_CLASS";
618618
dbg_info("Q_ENUM $enum_helper");
619619
if ($python_output ne ''){
620620
my $pl;

tests/src/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ IF (WITH_SERVER)
88
ADD_PYTHON_TEST(PyQgsLocalServer test_qgis_local_server.py)
99
ENDIF (WITH_SERVER)
1010

11+
ADD_PYTHON_TEST(PyCoreAdittions test_core_additions.py)
1112
ADD_PYTHON_TEST(PyQgsActionManager test_qgsactionmanager.py)
1213
ADD_PYTHON_TEST(PyQgsAFSProvider test_provider_afs.py)
1314
ADD_PYTHON_TEST(PyQgsAggregateCalculator test_qgsaggregatecalculator.py)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for core additions
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = 'Denis Rouzaud'
10+
__date__ = '15.5.2018'
11+
__copyright__ = 'Copyright 2015, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
import qgis # NOQA
16+
import os
17+
18+
from qgis.testing import unittest, start_app
19+
from qgis.core import metaEnumFromValue, metaEnumFromType, QgsTolerance, QgsMapLayer
20+
import sip
21+
22+
start_app()
23+
24+
25+
class TestCoreAdditions(unittest.TestCase):
26+
27+
def testEnum(self):
28+
me = metaEnumFromValue(QgsTolerance.Pixels)
29+
self.assertIsNotNone(me)
30+
self.assertEqual(me.valueToKey(QgsTolerance.Pixels), 'Pixels')
31+
32+
# if using same variable twice (e.g. me = me2), this seg faults
33+
me2 = metaEnumFromValue(QgsTolerance.Pixels, True, QgsTolerance)
34+
self.assertIsNotNone(me)
35+
self.assertEqual(me2.valueToKey(QgsTolerance.Pixels), 'Pixels')
36+
37+
# do not provide an int
38+
with self.assertRaises(TypeError):
39+
metaEnumFromValue(1)
40+
41+
# QgsMapLayer.LayerType is not a Q_ENUM
42+
with self.assertRaises(ValueError):
43+
metaEnumFromValue(QgsMapLayer.LayerType)
44+
45+
46+
if __name__ == "__main__":
47+
unittest.main()

0 commit comments

Comments
 (0)