forked from AG_QGIS/Plugin_SN_Basis
111 lines
3.1 KiB
Python
111 lines
3.1 KiB
Python
"""
|
||
qt_compat.py – Einheitliche Qt-Kompatibilitätsschicht für QGIS-Plugins.
|
||
|
||
Ziele:
|
||
- PyQt6 bevorzugt
|
||
- Fallback auf PyQt5
|
||
- Mock-Modus, wenn kein Qt verfügbar ist (z. B. in Unittests)
|
||
- OR-fähige Fake-Enums im Mock-Modus
|
||
"""
|
||
|
||
QT_VERSION = 0 # 0 = Mock, 5 = PyQt5, 6 = PyQt6
|
||
|
||
# ---------------------------------------------------------
|
||
# Versuch: PyQt6 importieren
|
||
# ---------------------------------------------------------
|
||
try:
|
||
from PyQt6.QtWidgets import QMessageBox, QFileDialog
|
||
from PyQt6.QtCore import Qt, QEventLoop, QUrl
|
||
from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply
|
||
|
||
YES = QMessageBox.StandardButton.Yes
|
||
NO = QMessageBox.StandardButton.No
|
||
CANCEL = QMessageBox.StandardButton.Cancel
|
||
ICON_QUESTION = QMessageBox.Icon.Question
|
||
|
||
QT_VERSION = 6
|
||
|
||
def exec_dialog(dialog):
|
||
"""Einheitliche Ausführung eines Dialogs."""
|
||
return dialog.exec()
|
||
|
||
# ---------------------------------------------------------
|
||
# Versuch: PyQt5 importieren
|
||
# ---------------------------------------------------------
|
||
except Exception:
|
||
try:
|
||
from PyQt5.QtWidgets import QMessageBox, QFileDialog
|
||
from PyQt5.QtCore import Qt, QEventLoop, QUrl
|
||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||
|
||
YES = QMessageBox.Yes
|
||
NO = QMessageBox.No
|
||
CANCEL = QMessageBox.Cancel
|
||
ICON_QUESTION = QMessageBox.Question
|
||
|
||
QT_VERSION = 5
|
||
|
||
def exec_dialog(dialog):
|
||
return dialog.exec_()
|
||
|
||
# ---------------------------------------------------------
|
||
# Mock-Modus (kein Qt verfügbar)
|
||
# ---------------------------------------------------------
|
||
except Exception:
|
||
QT_VERSION = 0
|
||
|
||
class FakeEnum(int):
|
||
"""Ein OR-fähiger Enum-Ersatz für den Mock-Modus."""
|
||
def __or__(self, other):
|
||
return FakeEnum(int(self) | int(other))
|
||
|
||
class QMessageBox:
|
||
Yes = FakeEnum(1)
|
||
No = FakeEnum(2)
|
||
Cancel = FakeEnum(4)
|
||
Question = FakeEnum(8)
|
||
|
||
class QFileDialog:
|
||
"""Minimaler Mock für QFileDialog."""
|
||
@staticmethod
|
||
def getOpenFileName(*args, **kwargs):
|
||
return ("", "") # kein Dateipfad
|
||
|
||
YES = QMessageBox.Yes
|
||
NO = QMessageBox.No
|
||
CANCEL = QMessageBox.Cancel
|
||
ICON_QUESTION = QMessageBox.Question
|
||
|
||
def exec_dialog(dialog):
|
||
"""Mock-Ausführung: gibt YES zurück, außer Tests patchen es."""
|
||
return YES
|
||
# -------------------------
|
||
# Mock Netzwerk-Klassen
|
||
# -------------------------
|
||
class QEventLoop:
|
||
def exec(self):
|
||
return 0
|
||
|
||
def quit(self):
|
||
pass
|
||
|
||
class QUrl(str):
|
||
pass
|
||
|
||
class QNetworkRequest:
|
||
def __init__(self, url):
|
||
self.url = url
|
||
|
||
class QNetworkReply:
|
||
def __init__(self):
|
||
self._data = b""
|
||
|
||
def readAll(self):
|
||
return self._data
|
||
|
||
def error(self):
|
||
return 0
|
||
|
||
def exec_dialog(dialog):
|
||
return YES
|
||
|