Skip to content

Commit 7692931

Browse files
authored
Merge pull request #91 from Loop3D/copilot/fix-qgis-4-compatibility
Fix QGIS 4 compatibility: replace removed PyQt6.Qt monolithic import
2 parents 5119104 + f0ce0b6 commit 7692931

57 files changed

Lines changed: 988 additions & 460 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/linter.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
- name: Install dependencies
3939
run: |
4040
python -m pip install --upgrade pip
41-
pip install black ruff
41+
pip install black "ruff==0.15.22"
4242
- name: Autoformat with black
4343
run: |
4444
black .

loopstructural/__about__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def plugin_metadata_as_dict() -> dict:
5555
config.read(PLG_METADATA_FILE.resolve(), encoding="UTF-8")
5656
return {s: dict(config.items(s)) for s in config.sections()}
5757
else:
58-
raise IOError("Plugin metadata.txt not found at: %s" % PLG_METADATA_FILE)
58+
raise OSError("Plugin metadata.txt not found at: %s" % PLG_METADATA_FILE)
5959

6060

6161
# ############################################################################
@@ -66,7 +66,7 @@ def plugin_metadata_as_dict() -> dict:
6666
__plugin_md__: dict = plugin_metadata_as_dict()
6767

6868
__author__: str = __plugin_md__.get("general").get("author")
69-
__copyright__: str = "2024 - {0}, {1}".format(date.today().year, __author__)
69+
__copyright__: str = f"2024 - {date.today().year}, {__author__}"
7070
__email__: str = __plugin_md__.get("general").get("email")
7171
__icon_path__: Path = DIR_PLUGIN_ROOT.resolve() / __plugin_md__.get("general").get("icon")
7272
__keywords__: list = [

loopstructural/debug_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,13 @@ def log_params(self, context_label: str, params: Any):
245245
"""
246246
try:
247247
self.plugin.log(
248-
message=f"[map2loop] {context_label} parameters: {str(params)}",
248+
message=f"[map2loop] {context_label} parameters: {params!s}",
249249
log_level=0,
250250
)
251251
except Exception as err:
252252
self.plugin.log(
253253
message=(
254-
f"[map2loop] {context_label} parameters (stringified due to {err}): {str(params)}"
254+
f"[map2loop] {context_label} parameters (stringified due to {err}): {params!s}"
255255
),
256256
log_level=0,
257257
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# compat.py
2+
from qgis.PyQt.QtCore import QVariant
3+
4+
try:
5+
from qgis.PyQt.QtCore import QMetaType
6+
7+
# We create a proxy class to mimic the old QVariant.Type behavior
8+
class QVariantProxy:
9+
Type = QMetaType.Type
10+
# Add common types here if needed
11+
Int = QMetaType.Type.Int
12+
Double = QMetaType.Type.Double
13+
String = QMetaType.Type.QString
14+
Bool = QMetaType.Type.Bool
15+
16+
# In QGIS 4, we use our proxy
17+
QVariantCompat = QVariantProxy
18+
except (ImportError, AttributeError):
19+
# In QGIS 3, QVariant already has .Type
20+
QVariantCompat = QVariant

loopstructural/gui/data_conversion/configuration.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
from __future__ import annotations
44

5+
from collections.abc import Iterable, MutableMapping
56
from copy import deepcopy
6-
from typing import Any, Dict, Iterable, MutableMapping
7+
from typing import Any, Dict
78

89

910
class Config:

loopstructural/gui/data_conversion/data_conversion_widget.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

55
import os
66
import re
7+
from collections.abc import Iterable, Mapping
78
from dataclasses import dataclass
8-
from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple
9+
from typing import Any, Dict, List, Optional, Tuple
910

1011
from LoopDataConverter import Datatype, InputData, LoopConverter, SurveyName
11-
from PyQt5.QtCore import Qt, QTimer
12-
from PyQt5.QtWidgets import (
12+
from qgis.core import QgsMapLayerProxyModel, QgsProject, QgsVectorLayer
13+
from qgis.gui import QgsMapLayerComboBox
14+
from qgis.PyQt.QtCore import Qt, QTimer
15+
from qgis.PyQt.QtWidgets import (
1316
QComboBox,
1417
QDialog,
1518
QDialogButtonBox,
@@ -21,8 +24,6 @@
2124
QVBoxLayout,
2225
QWidget,
2326
)
24-
from qgis.core import QgsMapLayerProxyModel, QgsProject, QgsVectorLayer
25-
from qgis.gui import QgsMapLayerComboBox
2627

2728
from ...main.helpers import ColumnMatcher
2829
from ...main.vectorLayerWrapper import QgsLayerFromDataFrame, QgsLayerFromGeoDataFrame

loopstructural/gui/dlg_settings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from qgis.core import Qgis, QgsApplication
1313
from qgis.gui import QgsOptionsPageWidget, QgsOptionsWidgetFactory
1414
from qgis.PyQt import uic
15-
from qgis.PyQt.Qt import QUrl
15+
from qgis.PyQt.QtCore import QUrl
1616
from qgis.PyQt.QtGui import QDesktopServices, QIcon
1717

1818
# project
@@ -30,7 +30,7 @@
3030
# ########## Globals ###############
3131
# ##################################
3232

33-
FORM_CLASS, _ = uic.loadUiType(Path(__file__).parent / "{}.ui".format(Path(__file__).stem))
33+
FORM_CLASS, _ = uic.loadUiType(Path(__file__).parent / f"{Path(__file__).stem}.ui")
3434

3535

3636
# ############################################################################
@@ -48,7 +48,7 @@ def __init__(self, parent):
4848

4949
# load UI and set objectName
5050
self.setupUi(self)
51-
self.setObjectName("mOptionsPage{}".format(__title__))
51+
self.setObjectName(f"mOptionsPage{__title__}")
5252

5353
_report_context_message = quote(
5454
"> Reported from plugin settings\n\n"

loopstructural/gui/loop_widget.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
interface for interacting with LoopStructural features inside QGIS.
66
"""
77

8-
from PyQt5.QtWidgets import QTabWidget, QVBoxLayout, QWidget
8+
from qgis.PyQt.QtWidgets import QTabWidget, QVBoxLayout, QWidget
99

1010
from .modelling.modelling_widget import ModellingWidget
1111
from .visualisation.visualisation_widget import VisualisationWidget

loopstructural/gui/map2loop_tools/basal_contacts_widget.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import os
44

5-
from PyQt5.QtWidgets import QMessageBox, QWidget
65
from qgis.core import QgsProject, QgsVectorFileWriter
76
from qgis.PyQt import uic
7+
from qgis.PyQt.QtWidgets import QMessageBox, QWidget
88

99
from ...main.helpers import ColumnMatcher, get_layer_names
1010
from ...main.m2l_api import extract_basal_contacts
@@ -277,11 +277,11 @@ def set_parameters(self, params):
277277
params : dict
278278
Dictionary of parameters to set.
279279
"""
280-
if 'geology_layer' in params and params['geology_layer']:
280+
if params.get('geology_layer'):
281281
self.geologyLayerComboBox.setLayer(params['geology_layer'])
282-
if 'faults_layer' in params and params['faults_layer']:
282+
if params.get('faults_layer'):
283283
self.faultsLayerComboBox.setLayer(params['faults_layer'])
284-
if 'ignore_units' in params and params['ignore_units']:
284+
if params.get('ignore_units'):
285285
self.ignoreUnitsLineEdit.setText(', '.join(params['ignore_units']))
286286
if 'all_contacts' in params:
287287
self.allContactsCheckBox.setChecked(params['all_contacts'])
@@ -310,7 +310,7 @@ def _is_null_like(v):
310310
if v is None:
311311
return True
312312
# PyQGIS QVariant null check
313-
if hasattr(v, "isNull") and callable(getattr(v, "isNull")) and v.isNull():
313+
if hasattr(v, "isNull") and callable(v.isNull) and v.isNull():
314314
return True
315315
# Empty strings or literal "NULL" (case-insensitive)
316316
if isinstance(v, str):

loopstructural/gui/map2loop_tools/dialogs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
instead of QGIS processing algorithms.
55
"""
66

7-
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout
7+
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout
88

99

1010
class SamplerDialog(QDialog):
@@ -23,7 +23,9 @@ def setup_ui(self):
2323
from .sampler_widget import SamplerWidget
2424

2525
layout = QVBoxLayout(self)
26-
self.widget = SamplerWidget(self, data_manager=self.data_manager, debug_manager=self.debug_manager)
26+
self.widget = SamplerWidget(
27+
self, data_manager=self.data_manager, debug_manager=self.debug_manager
28+
)
2729
layout.addWidget(self.widget)
2830

2931
# Replace the run button with dialog buttons

0 commit comments

Comments
 (0)