2025-12-19 14:29:52 +01:00
|
|
|
|
"""
|
2026-03-04 15:32:49 +01:00
|
|
|
|
sn_basis/functions/qt_wrapper.py – zentrale Qt-Abstraktion (PyQt6 primär / PyQt5 Fallback / Mock)
|
2025-12-19 14:29:52 +01:00
|
|
|
|
"""
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from typing import Optional, Type, Any, Callable
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# Globale Qt-Symbole (werden dynamisch gesetzt)
|
|
|
|
|
|
QT_VERSION = 0 # 0 = Mock, 5 = PyQt5, 6 = PyQt6
|
2025-12-19 14:29:52 +01:00
|
|
|
|
YES: Optional[Any] = None
|
|
|
|
|
|
NO: Optional[Any] = None
|
|
|
|
|
|
CANCEL: Optional[Any] = None
|
|
|
|
|
|
ICON_QUESTION: Optional[Any] = None
|
2026-03-11 20:56:02 +01:00
|
|
|
|
QVariant: Type[Any] = object
|
|
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-06 10:20:40 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# Qt-Klassen (werden dynamisch gesetzt)
|
|
|
|
|
|
QDockWidget: Type[Any] = object
|
|
|
|
|
|
QMessageBox: Type[Any] = object
|
|
|
|
|
|
QFileDialog: Type[Any] = object
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QProgressDialog: Type[Any] = object
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QEventLoop: Type[Any] = object
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QTimer: Type[Any] = object
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QUrl: Type[Any] = object
|
|
|
|
|
|
QNetworkRequest: Type[Any] = object
|
|
|
|
|
|
QNetworkReply: Type[Any] = object
|
|
|
|
|
|
QCoreApplication: Type[Any] = object
|
|
|
|
|
|
QWidget: Type[Any] = object
|
|
|
|
|
|
QGridLayout: Type[Any] = object
|
|
|
|
|
|
QLabel: Type[Any] = object
|
|
|
|
|
|
QLineEdit: Type[Any] = object
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog: Type[Any] = object
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QGroupBox: Type[Any] = object
|
|
|
|
|
|
QVBoxLayout: Type[Any] = object
|
|
|
|
|
|
QPushButton: Type[Any] = object
|
|
|
|
|
|
QAction: Type[Any] = object
|
|
|
|
|
|
QMenu: Type[Any] = object
|
|
|
|
|
|
QToolBar: Type[Any] = object
|
|
|
|
|
|
QActionGroup: Type[Any] = object
|
|
|
|
|
|
QTabWidget: Type[Any] = object
|
|
|
|
|
|
QToolButton: Type[Any] = object
|
|
|
|
|
|
QSizePolicy: Type[Any] = object
|
|
|
|
|
|
Qt: Type[Any] = object
|
|
|
|
|
|
QComboBox: Type[Any] = object
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QCheckBox: Type[Any] = object
|
2026-03-06 10:20:40 +01:00
|
|
|
|
QHBoxLayout: Type[Any] = object
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QFont: Type[Any] = object
|
2026-06-19 11:47:36 +02:00
|
|
|
|
QSettings: Type[Any] = object
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QDialog: Type[Any] = object
|
|
|
|
|
|
QDialogButtonBox: Type[Any] = object
|
|
|
|
|
|
QListWidget: Type[Any] = object
|
|
|
|
|
|
QListWidgetItem: Type[Any] = object
|
|
|
|
|
|
QAbstractItemView: Type[Any] = object
|
2026-08-28 13:54:43 +02:00
|
|
|
|
QTableWidget: Type[Any] = object
|
|
|
|
|
|
QTableWidgetItem: Type[Any] = object
|
|
|
|
|
|
QTableWidgetSelectionRange: Type[Any] = object
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QIcon: Type[Any] = object
|
2026-03-06 10:20:40 +01:00
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
def exec_dialog(dialog: Any) -> Any:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
"""Führt Dialog modal aus (Qt6: exec(), Qt5: exec_(), Mock: YES)"""
|
|
|
|
|
|
raise NotImplementedError("Qt nicht initialisiert")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def debug_qt_status() -> None:
|
|
|
|
|
|
"""Debug: Zeigt Qt-Status für Troubleshooting."""
|
|
|
|
|
|
print(f"🔍 QT_VERSION: {QT_VERSION}")
|
|
|
|
|
|
print(f"🔍 QMessageBox Typ: {getattr(QMessageBox, '__name__', type(QMessageBox).__name__)}")
|
|
|
|
|
|
print(f"🔍 YES Wert: {YES} (Typ: {type(YES) if YES is not None else 'None'})")
|
|
|
|
|
|
|
|
|
|
|
|
if QT_VERSION == 0:
|
|
|
|
|
|
print("❌ MOCK-MODUS AKTIV! Keine Dialoge möglich!")
|
|
|
|
|
|
elif QT_VERSION == 5:
|
|
|
|
|
|
print("✅ PyQt5 geladen (Fallback) – Dialoge sollten funktionieren!")
|
|
|
|
|
|
elif QT_VERSION == 6:
|
|
|
|
|
|
print("✅ PyQt6 geladen (primär) – Dialoge sollten funktionieren!")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("❓ Unbekannte Qt-Version!")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# --------------------------- PYQT6 PRIMÄR ---------------------------
|
2025-12-19 14:29:52 +01:00
|
|
|
|
try:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from qgis.PyQt.QtWidgets import (
|
|
|
|
|
|
QMessageBox as _QMessageBox,
|
|
|
|
|
|
QFileDialog as _QFileDialog,
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QProgressDialog as _QProgressDialog,
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QWidget as _QWidget,
|
|
|
|
|
|
QGridLayout as _QGridLayout,
|
|
|
|
|
|
QLabel as _QLabel,
|
|
|
|
|
|
QLineEdit as _QLineEdit,
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog as _QInputDialog,
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QGroupBox as _QGroupBox,
|
|
|
|
|
|
QVBoxLayout as _QVBoxLayout,
|
|
|
|
|
|
QPushButton as _QPushButton,
|
|
|
|
|
|
QAction as _QAction,
|
|
|
|
|
|
QMenu as _QMenu,
|
|
|
|
|
|
QToolBar as _QToolBar,
|
|
|
|
|
|
QActionGroup as _QActionGroup,
|
|
|
|
|
|
QDockWidget as _QDockWidget,
|
|
|
|
|
|
QTabWidget as _QTabWidget,
|
|
|
|
|
|
QToolButton as _QToolButton,
|
|
|
|
|
|
QSizePolicy as _QSizePolicy,
|
|
|
|
|
|
QComboBox as _QComboBox,
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QCheckBox as _QCheckBox,
|
2026-03-06 10:20:40 +01:00
|
|
|
|
QHBoxLayout as _QHBoxLayout,
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QDialog as _QDialog,
|
|
|
|
|
|
QDialogButtonBox as _QDialogButtonBox,
|
|
|
|
|
|
QListWidget as _QListWidget,
|
|
|
|
|
|
QListWidgetItem as _QListWidgetItem,
|
|
|
|
|
|
QAbstractItemView as _QAbstractItemView,
|
2026-08-28 13:54:43 +02:00
|
|
|
|
QTableWidget as _QTableWidget,
|
|
|
|
|
|
QTableWidgetItem as _QTableWidgetItem,
|
|
|
|
|
|
QTableWidgetSelectionRange as _QTableWidgetSelectionRange,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
)
|
2026-08-27 15:13:43 +02:00
|
|
|
|
from qgis.PyQt.QtGui import QFont as _QFont, QIcon as _QIcon
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from qgis.PyQt.QtCore import (
|
|
|
|
|
|
QEventLoop as _QEventLoop,
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QTimer as _QTimer,
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QUrl as _QUrl,
|
|
|
|
|
|
QCoreApplication as _QCoreApplication,
|
|
|
|
|
|
Qt as _Qt,
|
2026-06-19 11:47:36 +02:00
|
|
|
|
QVariant as _QVariant,
|
|
|
|
|
|
QSettings as _QSettings,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
)
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from qgis.PyQt.QtNetwork import (
|
|
|
|
|
|
QNetworkRequest as _QNetworkRequest,
|
|
|
|
|
|
QNetworkReply as _QNetworkReply,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ✅ ALLE GLOBALS ZUWEISEN
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QT_VERSION = 6
|
|
|
|
|
|
QMessageBox = _QMessageBox
|
|
|
|
|
|
QFileDialog = _QFileDialog
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QProgressDialog = _QProgressDialog
|
|
|
|
|
|
QProgressDialog = _QProgressDialog
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QEventLoop = _QEventLoop
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QTimer = _QTimer
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QUrl = _QUrl
|
|
|
|
|
|
QNetworkRequest = _QNetworkRequest
|
|
|
|
|
|
QNetworkReply = _QNetworkReply
|
|
|
|
|
|
QCoreApplication = _QCoreApplication
|
2026-03-04 15:32:49 +01:00
|
|
|
|
Qt = _Qt
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QDockWidget = _QDockWidget
|
|
|
|
|
|
QWidget = _QWidget
|
|
|
|
|
|
QGridLayout = _QGridLayout
|
|
|
|
|
|
QLabel = _QLabel
|
|
|
|
|
|
QLineEdit = _QLineEdit
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog = _QInputDialog
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QGroupBox = _QGroupBox
|
|
|
|
|
|
QVBoxLayout = _QVBoxLayout
|
|
|
|
|
|
QPushButton = _QPushButton
|
|
|
|
|
|
QAction = _QAction
|
|
|
|
|
|
QMenu = _QMenu
|
|
|
|
|
|
QToolBar = _QToolBar
|
|
|
|
|
|
QActionGroup = _QActionGroup
|
|
|
|
|
|
QTabWidget = _QTabWidget
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QToolButton = _QToolButton
|
|
|
|
|
|
QSizePolicy = _QSizePolicy
|
|
|
|
|
|
QComboBox = _QComboBox
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QCheckBox = _QCheckBox
|
2026-03-06 10:20:40 +01:00
|
|
|
|
QVariant = _QVariant
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QHBoxLayout = _QHBoxLayout
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QFont = _QFont
|
2026-06-19 11:47:36 +02:00
|
|
|
|
QSettings = _QSettings
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QDialog = _QDialog
|
|
|
|
|
|
QDialogButtonBox = _QDialogButtonBox
|
|
|
|
|
|
QListWidget = _QListWidget
|
|
|
|
|
|
QListWidgetItem = _QListWidgetItem
|
|
|
|
|
|
QAbstractItemView = _QAbstractItemView
|
2026-08-28 13:54:43 +02:00
|
|
|
|
QTableWidget = _QTableWidget
|
|
|
|
|
|
QTableWidgetItem = _QTableWidgetItem
|
|
|
|
|
|
QTableWidgetSelectionRange = _QTableWidgetSelectionRange
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QIcon = _QIcon
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# ✅ QT6 ENUMS
|
2025-12-19 14:29:52 +01:00
|
|
|
|
YES = QMessageBox.StandardButton.Yes
|
|
|
|
|
|
NO = QMessageBox.StandardButton.No
|
|
|
|
|
|
CANCEL = QMessageBox.StandardButton.Cancel
|
|
|
|
|
|
ICON_QUESTION = QMessageBox.Icon.Question
|
2026-03-06 10:20:40 +01:00
|
|
|
|
AcceptRole = QMessageBox.ButtonRole.AcceptRole
|
|
|
|
|
|
ActionRole = QMessageBox.ButtonRole.ActionRole
|
|
|
|
|
|
RejectRole = QMessageBox.ButtonRole.RejectRole
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
# Qt6 Enum-Aliase
|
2026-01-08 17:13:51 +01:00
|
|
|
|
ToolButtonTextBesideIcon = Qt.ToolButtonStyle.ToolButtonTextBesideIcon
|
|
|
|
|
|
ArrowDown = Qt.ArrowType.DownArrow
|
|
|
|
|
|
ArrowRight = Qt.ArrowType.RightArrow
|
|
|
|
|
|
SizePolicyPreferred = QSizePolicy.Policy.Preferred
|
|
|
|
|
|
SizePolicyMaximum = QSizePolicy.Policy.Maximum
|
|
|
|
|
|
DockWidgetMovable = QDockWidget.DockWidgetFeature.DockWidgetMovable
|
|
|
|
|
|
DockWidgetFloatable = QDockWidget.DockWidgetFeature.DockWidgetFloatable
|
|
|
|
|
|
DockWidgetClosable = QDockWidget.DockWidgetFeature.DockWidgetClosable
|
|
|
|
|
|
DockAreaLeft = Qt.DockWidgetArea.LeftDockWidgetArea
|
|
|
|
|
|
DockAreaRight = Qt.DockWidgetArea.RightDockWidgetArea
|
2026-08-27 15:13:43 +02:00
|
|
|
|
DialogAccepted = QDialog.DialogCode.Accepted
|
|
|
|
|
|
ExtendedSelection = QAbstractItemView.SelectionMode.ExtendedSelection
|
2026-08-28 13:54:43 +02:00
|
|
|
|
SelectRows = QAbstractItemView.SelectionBehavior.SelectRows
|
|
|
|
|
|
NoEditTriggers = QAbstractItemView.EditTrigger.NoEditTriggers
|
|
|
|
|
|
AscendingOrder = Qt.SortOrder.AscendingOrder
|
2026-08-27 15:13:43 +02:00
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
def exec_dialog(dialog: Any) -> Any:
|
|
|
|
|
|
return dialog.exec()
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
print(f"✅ qt_wrapper: PyQt6 geladen (QT_VERSION={QT_VERSION})")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# --------------------------- PYQT5 FALLBACK ---------------------------
|
|
|
|
|
|
except (ImportError, AttributeError):
|
2025-12-19 14:29:52 +01:00
|
|
|
|
try:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from PyQt5.QtWidgets import (
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QMessageBox as _QMessageBox,
|
|
|
|
|
|
QFileDialog as _QFileDialog,
|
|
|
|
|
|
QWidget as _QWidget,
|
|
|
|
|
|
QGridLayout as _QGridLayout,
|
|
|
|
|
|
QLabel as _QLabel,
|
|
|
|
|
|
QLineEdit as _QLineEdit,
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog as _QInputDialog,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QGroupBox as _QGroupBox,
|
|
|
|
|
|
QVBoxLayout as _QVBoxLayout,
|
|
|
|
|
|
QPushButton as _QPushButton,
|
|
|
|
|
|
QAction as _QAction,
|
|
|
|
|
|
QMenu as _QMenu,
|
|
|
|
|
|
QToolBar as _QToolBar,
|
|
|
|
|
|
QActionGroup as _QActionGroup,
|
|
|
|
|
|
QDockWidget as _QDockWidget,
|
|
|
|
|
|
QTabWidget as _QTabWidget,
|
2026-01-08 17:13:51 +01:00
|
|
|
|
QToolButton as _QToolButton,
|
|
|
|
|
|
QSizePolicy as _QSizePolicy,
|
2026-02-13 21:39:12 +01:00
|
|
|
|
QComboBox as _QComboBox,
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QCheckBox as _QCheckBox,
|
2026-03-06 10:20:40 +01:00
|
|
|
|
QHBoxLayout as _QHBoxLayout,
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QDialog as _QDialog,
|
|
|
|
|
|
QDialogButtonBox as _QDialogButtonBox,
|
|
|
|
|
|
QListWidget as _QListWidget,
|
|
|
|
|
|
QListWidgetItem as _QListWidgetItem,
|
|
|
|
|
|
QAbstractItemView as _QAbstractItemView,
|
2026-08-28 13:54:43 +02:00
|
|
|
|
QTableWidget as _QTableWidget,
|
|
|
|
|
|
QTableWidgetItem as _QTableWidgetItem,
|
|
|
|
|
|
QTableWidgetSelectionRange as _QTableWidgetSelectionRange,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
)
|
2026-08-27 15:13:43 +02:00
|
|
|
|
from PyQt5.QtGui import QFont as _QFont, QIcon as _QIcon
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from PyQt5.QtCore import (
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QEventLoop as _QEventLoop,
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QTimer as _QTimer,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QUrl as _QUrl,
|
|
|
|
|
|
QCoreApplication as _QCoreApplication,
|
2026-01-08 17:13:51 +01:00
|
|
|
|
Qt as _Qt,
|
2026-06-19 11:47:36 +02:00
|
|
|
|
QVariant as _QVariant,
|
|
|
|
|
|
QSettings as _QSettings,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
)
|
2026-03-04 15:32:49 +01:00
|
|
|
|
from PyQt5.QtNetwork import (
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QNetworkRequest as _QNetworkRequest,
|
|
|
|
|
|
QNetworkReply as _QNetworkReply,
|
|
|
|
|
|
)
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
# ✅ ALLE GLOBALS ZUWEISEN
|
|
|
|
|
|
QT_VERSION = 5
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QMessageBox = _QMessageBox
|
|
|
|
|
|
QFileDialog = _QFileDialog
|
|
|
|
|
|
QEventLoop = _QEventLoop
|
2026-03-12 16:14:02 +01:00
|
|
|
|
QTimer = _QTimer
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QUrl = _QUrl
|
|
|
|
|
|
QNetworkRequest = _QNetworkRequest
|
|
|
|
|
|
QNetworkReply = _QNetworkReply
|
|
|
|
|
|
QCoreApplication = _QCoreApplication
|
2026-03-04 15:32:49 +01:00
|
|
|
|
Qt = _Qt
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QDockWidget = _QDockWidget
|
|
|
|
|
|
QWidget = _QWidget
|
|
|
|
|
|
QGridLayout = _QGridLayout
|
|
|
|
|
|
QLabel = _QLabel
|
|
|
|
|
|
QLineEdit = _QLineEdit
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog = _QInputDialog
|
2025-12-19 14:29:52 +01:00
|
|
|
|
QGroupBox = _QGroupBox
|
|
|
|
|
|
QVBoxLayout = _QVBoxLayout
|
|
|
|
|
|
QPushButton = _QPushButton
|
|
|
|
|
|
QAction = _QAction
|
|
|
|
|
|
QMenu = _QMenu
|
|
|
|
|
|
QToolBar = _QToolBar
|
|
|
|
|
|
QActionGroup = _QActionGroup
|
|
|
|
|
|
QTabWidget = _QTabWidget
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QToolButton = _QToolButton
|
|
|
|
|
|
QSizePolicy = _QSizePolicy
|
|
|
|
|
|
QComboBox = _QComboBox
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QCheckBox = _QCheckBox
|
2026-03-06 10:20:40 +01:00
|
|
|
|
QVariant = _QVariant
|
2026-03-20 12:01:16 +01:00
|
|
|
|
QHBoxLayout= _QHBoxLayout
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QFont = _QFont
|
2026-06-19 11:47:36 +02:00
|
|
|
|
QSettings = _QSettings
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QDialog = _QDialog
|
|
|
|
|
|
QDialogButtonBox = _QDialogButtonBox
|
|
|
|
|
|
QListWidget = _QListWidget
|
|
|
|
|
|
QListWidgetItem = _QListWidgetItem
|
|
|
|
|
|
QAbstractItemView = _QAbstractItemView
|
2026-08-28 13:54:43 +02:00
|
|
|
|
QTableWidget = _QTableWidget
|
|
|
|
|
|
QTableWidgetItem = _QTableWidgetItem
|
|
|
|
|
|
QTableWidgetSelectionRange = _QTableWidgetSelectionRange
|
2026-08-27 15:13:43 +02:00
|
|
|
|
QIcon = _QIcon
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# ✅ PYQT5 ENUMS
|
2025-12-19 14:29:52 +01:00
|
|
|
|
YES = QMessageBox.Yes
|
|
|
|
|
|
NO = QMessageBox.No
|
|
|
|
|
|
CANCEL = QMessageBox.Cancel
|
|
|
|
|
|
ICON_QUESTION = QMessageBox.Question
|
2026-03-06 10:20:40 +01:00
|
|
|
|
AcceptRole = QMessageBox.AcceptRole
|
|
|
|
|
|
ActionRole = QMessageBox.ActionRole
|
|
|
|
|
|
RejectRole = QMessageBox.RejectRole
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
# PyQt5 Enum-Aliase
|
2026-01-08 17:13:51 +01:00
|
|
|
|
ToolButtonTextBesideIcon = Qt.ToolButtonTextBesideIcon
|
|
|
|
|
|
ArrowDown = Qt.DownArrow
|
|
|
|
|
|
ArrowRight = Qt.RightArrow
|
|
|
|
|
|
SizePolicyPreferred = QSizePolicy.Preferred
|
|
|
|
|
|
SizePolicyMaximum = QSizePolicy.Maximum
|
|
|
|
|
|
DockWidgetMovable = QDockWidget.DockWidgetMovable
|
|
|
|
|
|
DockWidgetFloatable = QDockWidget.DockWidgetFloatable
|
|
|
|
|
|
DockWidgetClosable = QDockWidget.DockWidgetClosable
|
|
|
|
|
|
DockAreaLeft = Qt.LeftDockWidgetArea
|
|
|
|
|
|
DockAreaRight = Qt.RightDockWidgetArea
|
2026-08-27 15:13:43 +02:00
|
|
|
|
DialogAccepted = QDialog.Accepted
|
|
|
|
|
|
ExtendedSelection = QAbstractItemView.ExtendedSelection
|
2026-08-28 13:54:43 +02:00
|
|
|
|
SelectRows = QAbstractItemView.SelectRows
|
|
|
|
|
|
NoEditTriggers = QAbstractItemView.NoEditTriggers
|
|
|
|
|
|
AscendingOrder = Qt.AscendingOrder
|
2026-08-27 15:13:43 +02:00
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
def exec_dialog(dialog: Any) -> Any:
|
|
|
|
|
|
return dialog.exec_()
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
print(f"✅ qt_wrapper: PyQt5 Fallback geladen (QT_VERSION={QT_VERSION})")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# --------------------------- MOCK-MODUS ---------------------------
|
2025-12-19 14:29:52 +01:00
|
|
|
|
except Exception:
|
|
|
|
|
|
QT_VERSION = 0
|
2026-03-04 15:32:49 +01:00
|
|
|
|
print("⚠️ qt_wrapper: Mock-Modus aktiviert (QT_VERSION=0)")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# Fake Enum für Bit-Operationen
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class FakeEnum(int):
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __or__(self, other: Any) -> "FakeEnum":
|
2025-12-19 14:29:52 +01:00
|
|
|
|
return FakeEnum(int(self) | int(other))
|
|
|
|
|
|
|
|
|
|
|
|
YES = FakeEnum(1)
|
|
|
|
|
|
NO = FakeEnum(2)
|
|
|
|
|
|
CANCEL = FakeEnum(4)
|
|
|
|
|
|
ICON_QUESTION = FakeEnum(8)
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
# Im Mock-Block von qt_wrapper.py:
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockQMessageBox:
|
|
|
|
|
|
Yes = YES
|
|
|
|
|
|
No = NO
|
|
|
|
|
|
Cancel = CANCEL
|
|
|
|
|
|
Question = ICON_QUESTION
|
2026-03-06 10:20:40 +01:00
|
|
|
|
AcceptRole = 0
|
|
|
|
|
|
ActionRole = 3
|
|
|
|
|
|
RejectRole = 1
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
def question(cls, parent, title, message, buttons, default_button):
|
|
|
|
|
|
"""Mock: Gibt immer default_button zurück"""
|
|
|
|
|
|
print(f"🔍 Mock QMessageBox.question: '{title}' → {default_button}")
|
|
|
|
|
|
return default_button
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QMessageBox = _MockQMessageBox
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockQFileDialog:
|
|
|
|
|
|
@staticmethod
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def getOpenFileName(*args, **kwargs): return ("", "")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
@staticmethod
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def getSaveFileName(*args, **kwargs): return ("", "")
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QFileDialog = _MockQFileDialog
|
|
|
|
|
|
|
2026-03-20 14:01:57 +01:00
|
|
|
|
class _MockQInputDialog:
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
def getText(parent, title, label, mode=None, text=""):
|
|
|
|
|
|
return text, True
|
|
|
|
|
|
|
2026-08-28 13:54:43 +02:00
|
|
|
|
@staticmethod
|
|
|
|
|
|
def getItem(parent, title, label, items, current=0, editable=False):
|
|
|
|
|
|
return (items[current] if items else ""), True
|
|
|
|
|
|
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QInputDialog = _MockQInputDialog
|
|
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockQEventLoop:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def exec(self) -> int: return 0
|
|
|
|
|
|
def quit(self) -> None: pass
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QEventLoop = _MockQEventLoop
|
|
|
|
|
|
|
2026-03-12 16:14:02 +01:00
|
|
|
|
class _MockQTimer:
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self.timeout = type('Signal', (), {
|
|
|
|
|
|
'connect': lambda s, cb: None,
|
|
|
|
|
|
})()
|
|
|
|
|
|
def setSingleShot(self, v: bool) -> None: pass
|
|
|
|
|
|
def start(self, ms: int) -> None: pass
|
|
|
|
|
|
def stop(self) -> None: pass
|
|
|
|
|
|
|
|
|
|
|
|
QTimer = _MockQTimer
|
|
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockQUrl(str):
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def isValid(self) -> bool: return True
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QUrl = _MockQUrl
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQNetworkRequest:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, url: Any): self.url = url
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QNetworkRequest = _MockQNetworkRequest
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQNetworkReply:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def error(self) -> int: return 0
|
|
|
|
|
|
def errorString(self) -> str: return ""
|
|
|
|
|
|
def readAll(self) -> bytes: return b""
|
|
|
|
|
|
def deleteLater(self) -> None: pass
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QNetworkReply = _MockQNetworkReply
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
class _MockWidget: pass
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockLayout:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._widgets = []
|
|
|
|
|
|
def addWidget(self, widget): self._widgets.append(widget)
|
|
|
|
|
|
def addLayout(self, layout): pass
|
|
|
|
|
|
def addStretch(self, *args, **kwargs): pass
|
|
|
|
|
|
def setSpacing(self, *args, **kwargs): pass
|
|
|
|
|
|
def setContentsMargins(self, *args, **kwargs): pass
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
class _MockLabel:
|
|
|
|
|
|
def __init__(self, text: str = ""): self._text = text
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockLineEdit:
|
2026-03-20 14:01:57 +01:00
|
|
|
|
Normal = 0
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._text = ""
|
|
|
|
|
|
def text(self) -> str: return self._text
|
|
|
|
|
|
def setText(self, value: str) -> None: self._text = value
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
2026-03-20 14:01:57 +01:00
|
|
|
|
class _MockFont:
|
|
|
|
|
|
def __init__(self, family: str = "", pointSize: int = 10):
|
|
|
|
|
|
self.family = family
|
|
|
|
|
|
self.pointSize = pointSize
|
|
|
|
|
|
|
|
|
|
|
|
class _MockButton:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self.clicked = lambda *a, **k: None
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QWidget = _MockWidget
|
|
|
|
|
|
QGridLayout = _MockLayout
|
|
|
|
|
|
QLabel = _MockLabel
|
|
|
|
|
|
QLineEdit = _MockLineEdit
|
|
|
|
|
|
QGroupBox = _MockWidget
|
|
|
|
|
|
QVBoxLayout = _MockLayout
|
|
|
|
|
|
QPushButton = _MockButton
|
2026-03-20 14:01:57 +01:00
|
|
|
|
QFont = _MockFont
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QCoreApplication = object()
|
|
|
|
|
|
|
2026-01-08 17:13:51 +01:00
|
|
|
|
class _MockQt:
|
|
|
|
|
|
ToolButtonTextBesideIcon = 0
|
|
|
|
|
|
ArrowDown = 1
|
|
|
|
|
|
ArrowRight = 2
|
2026-03-04 15:32:49 +01:00
|
|
|
|
LeftDockWidgetArea = 1
|
|
|
|
|
|
RightDockWidgetArea = 2
|
2026-01-08 17:13:51 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
Qt = _MockQt()
|
2026-01-08 17:13:51 +01:00
|
|
|
|
ToolButtonTextBesideIcon = Qt.ToolButtonTextBesideIcon
|
|
|
|
|
|
ArrowDown = Qt.ArrowDown
|
|
|
|
|
|
ArrowRight = Qt.ArrowRight
|
2026-03-04 15:32:49 +01:00
|
|
|
|
DockAreaLeft = Qt.LeftDockWidgetArea
|
|
|
|
|
|
DockAreaRight = Qt.RightDockWidgetArea
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockQDockWidget(_MockWidget):
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._object_name = ""
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def setObjectName(self, name: str) -> None: self._object_name = name
|
|
|
|
|
|
def objectName(self) -> str: return self._object_name
|
|
|
|
|
|
def show(self) -> None: pass
|
|
|
|
|
|
def deleteLater(self) -> None: pass
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QDockWidget = _MockQDockWidget
|
2026-03-04 15:32:49 +01:00
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
class _MockAction:
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._checked = False
|
|
|
|
|
|
self.triggered = lambda *a, **k: None
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def setToolTip(self, text: str) -> None: pass
|
|
|
|
|
|
def setCheckable(self, value: bool) -> None: pass
|
|
|
|
|
|
def setChecked(self, value: bool) -> None: self._checked = value
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockMenu:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._actions = []
|
|
|
|
|
|
def addAction(self, action): self._actions.append(action)
|
|
|
|
|
|
def removeAction(self, action):
|
|
|
|
|
|
if action in self._actions: self._actions.remove(action)
|
|
|
|
|
|
def clear(self): self._actions.clear()
|
|
|
|
|
|
def menuAction(self): return self
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockToolBar:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._actions = []
|
|
|
|
|
|
def setObjectName(self, name: str) -> None: pass
|
|
|
|
|
|
def addAction(self, action): self._actions.append(action)
|
|
|
|
|
|
def removeAction(self, action):
|
|
|
|
|
|
if action in self._actions: self._actions.remove(action)
|
|
|
|
|
|
def clear(self): self._actions.clear()
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockActionGroup:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._actions = []
|
|
|
|
|
|
def setExclusive(self, value: bool) -> None: pass
|
|
|
|
|
|
def addAction(self, action): self._actions.append(action)
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QAction = _MockAction
|
|
|
|
|
|
QMenu = _MockMenu
|
|
|
|
|
|
QToolBar = _MockToolBar
|
|
|
|
|
|
QActionGroup = _MockActionGroup
|
|
|
|
|
|
|
2026-01-08 17:13:51 +01:00
|
|
|
|
class _MockToolButton(_MockWidget):
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._checked = False
|
|
|
|
|
|
self.toggled = lambda *a, **k: None
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def setText(self, text: str) -> None: pass
|
|
|
|
|
|
def setCheckable(self, value: bool) -> None: pass
|
|
|
|
|
|
def setChecked(self, value: bool) -> None: self._checked = value
|
|
|
|
|
|
def setToolButtonStyle(self, *args, **kwargs): pass
|
|
|
|
|
|
def setArrowType(self, *args, **kwargs): pass
|
|
|
|
|
|
def setStyleSheet(self, *args, **kwargs): pass
|
2026-01-08 17:13:51 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QToolButton = _MockToolButton
|
2026-01-08 17:13:51 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockQSizePolicy:
|
|
|
|
|
|
Preferred = 3
|
2026-03-04 15:32:49 +01:00
|
|
|
|
Maximum = 2
|
2026-01-08 17:13:51 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QSizePolicy = _MockQSizePolicy
|
2026-01-08 17:13:51 +01:00
|
|
|
|
SizePolicyPreferred = QSizePolicy.Preferred
|
|
|
|
|
|
SizePolicyMaximum = QSizePolicy.Maximum
|
|
|
|
|
|
DockWidgetMovable = 1
|
|
|
|
|
|
DockWidgetFloatable = 2
|
|
|
|
|
|
DockWidgetClosable = 4
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
class _MockTabWidget:
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def __init__(self, *args, **kwargs): self._tabs = []
|
|
|
|
|
|
def addTab(self, widget, title: str): self._tabs.append((widget, title))
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QTabWidget = _MockTabWidget
|
|
|
|
|
|
|
2026-02-13 21:39:12 +01:00
|
|
|
|
class _MockComboBox:
|
|
|
|
|
|
def __init__(self, parent=None):
|
2026-08-27 15:13:43 +02:00
|
|
|
|
self._items = [] # Liste von (text, userData)
|
2026-02-13 21:39:12 +01:00
|
|
|
|
self._index = -1
|
2026-03-04 15:32:49 +01:00
|
|
|
|
self.currentTextChanged = type('Signal', (), {'connect': lambda s, cb: None, 'emit': lambda s, v: None})()
|
2026-08-27 15:13:43 +02:00
|
|
|
|
def addItem(self, text: str, userData=None) -> None:
|
|
|
|
|
|
self._items.append((text, userData))
|
|
|
|
|
|
if self._index < 0:
|
|
|
|
|
|
self._index = 0
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def addItems(self, items): [self.addItem(it) for it in items]
|
2026-08-27 15:13:43 +02:00
|
|
|
|
def findText(self, text: str) -> int:
|
|
|
|
|
|
for i, (t, _) in enumerate(self._items):
|
|
|
|
|
|
if t == text:
|
|
|
|
|
|
return i
|
|
|
|
|
|
return -1
|
2026-02-13 21:39:12 +01:00
|
|
|
|
def setCurrentIndex(self, idx: int) -> None:
|
|
|
|
|
|
if 0 <= idx < len(self._items):
|
|
|
|
|
|
self._index = idx
|
|
|
|
|
|
self.currentTextChanged.emit(self.currentText())
|
|
|
|
|
|
def setCurrentText(self, text: str) -> None:
|
|
|
|
|
|
idx = self.findText(text)
|
2026-03-04 15:32:49 +01:00
|
|
|
|
if idx >= 0: self.setCurrentIndex(idx)
|
2026-02-13 21:39:12 +01:00
|
|
|
|
def currentText(self) -> str:
|
2026-08-27 15:13:43 +02:00
|
|
|
|
return self._items[self._index][0] if 0 <= self._index < len(self._items) else ""
|
|
|
|
|
|
def currentData(self):
|
|
|
|
|
|
return self._items[self._index][1] if 0 <= self._index < len(self._items) else None
|
|
|
|
|
|
def count(self) -> int:
|
|
|
|
|
|
return len(self._items)
|
2026-02-13 21:39:12 +01:00
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
QComboBox = _MockComboBox
|
|
|
|
|
|
|
2026-03-06 10:20:40 +01:00
|
|
|
|
|
|
|
|
|
|
# ---------------------------
|
|
|
|
|
|
# Mock für QVariant
|
|
|
|
|
|
# ---------------------------
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQVariant:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Minimaler Ersatz für QtCore.QVariant.
|
|
|
|
|
|
|
|
|
|
|
|
Ziel:
|
|
|
|
|
|
- Werte transparent durchreichen
|
|
|
|
|
|
- Typ-Konstanten bereitstellen
|
|
|
|
|
|
- Keine Qt-Abhängigkeiten
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# Typ-Konstanten (symbolisch, Werte egal)
|
|
|
|
|
|
Invalid = 0
|
|
|
|
|
|
Int = 1
|
|
|
|
|
|
Double = 2
|
|
|
|
|
|
String = 3
|
|
|
|
|
|
Bool = 4
|
|
|
|
|
|
Date = 5
|
|
|
|
|
|
DateTime = 6
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, value: Any = None):
|
|
|
|
|
|
self._value = value
|
|
|
|
|
|
|
|
|
|
|
|
def value(self) -> Any:
|
|
|
|
|
|
return self._value
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self) -> str:
|
|
|
|
|
|
return f"QVariant({self._value!r})"
|
|
|
|
|
|
|
|
|
|
|
|
# Optional: automatische Entpackung
|
|
|
|
|
|
def __int__(self):
|
|
|
|
|
|
return int(self._value)
|
|
|
|
|
|
|
|
|
|
|
|
def __float__(self):
|
|
|
|
|
|
return float(self._value)
|
|
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
|
return str(self._value)
|
|
|
|
|
|
QVariant = _MockQVariant
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQHBoxLayout:
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._widgets = []
|
|
|
|
|
|
|
|
|
|
|
|
def addWidget(self, widget):
|
|
|
|
|
|
self._widgets.append(widget)
|
|
|
|
|
|
|
|
|
|
|
|
def addLayout(self, layout):
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def addStretch(self, *args, **kwargs):
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def setSpacing(self, *args, **kwargs):
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def setContentsMargins(self, *args, **kwargs):
|
|
|
|
|
|
pass
|
|
|
|
|
|
QHBoxLayout = _MockQHBoxLayout
|
2026-03-20 12:01:16 +01:00
|
|
|
|
|
2026-06-19 11:47:36 +02:00
|
|
|
|
class _MockQSettings:
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._data: dict = {}
|
|
|
|
|
|
self._group = ""
|
|
|
|
|
|
|
|
|
|
|
|
def beginGroup(self, group: str) -> None:
|
|
|
|
|
|
self._group = group
|
|
|
|
|
|
|
|
|
|
|
|
def endGroup(self) -> None:
|
|
|
|
|
|
self._group = ""
|
|
|
|
|
|
|
|
|
|
|
|
def setValue(self, key: str, value: Any) -> None:
|
|
|
|
|
|
full = "%s/%s" % (self._group, key) if self._group else key
|
|
|
|
|
|
self._data[full] = value
|
|
|
|
|
|
|
|
|
|
|
|
def value(self, key: str, default: Any = "") -> Any:
|
|
|
|
|
|
full = "%s/%s" % (self._group, key) if self._group else key
|
|
|
|
|
|
return self._data.get(full, default)
|
|
|
|
|
|
|
|
|
|
|
|
def remove(self, key: str) -> None:
|
|
|
|
|
|
full = "%s/%s" % (self._group, key) if self._group else key
|
|
|
|
|
|
self._data.pop(full, None)
|
|
|
|
|
|
|
|
|
|
|
|
QSettings = _MockQSettings
|
|
|
|
|
|
|
2026-03-20 12:01:16 +01:00
|
|
|
|
class _MockQCheckBox:
|
|
|
|
|
|
def __init__(self, text: str = "", *args, **kwargs):
|
|
|
|
|
|
self._text = text
|
|
|
|
|
|
self._checked = False
|
|
|
|
|
|
|
|
|
|
|
|
def setText(self, text: str) -> None:
|
|
|
|
|
|
self._text = text
|
|
|
|
|
|
|
|
|
|
|
|
def isChecked(self) -> bool:
|
|
|
|
|
|
return self._checked
|
|
|
|
|
|
|
|
|
|
|
|
def setChecked(self, checked: bool) -> None:
|
|
|
|
|
|
self._checked = checked
|
|
|
|
|
|
|
|
|
|
|
|
QCheckBox = _MockQCheckBox
|
2026-08-27 15:13:43 +02:00
|
|
|
|
|
|
|
|
|
|
DialogAccepted = 1
|
|
|
|
|
|
ExtendedSelection = 3
|
2026-08-28 13:54:43 +02:00
|
|
|
|
SelectRows = 1
|
|
|
|
|
|
NoEditTriggers = 0
|
|
|
|
|
|
AscendingOrder = 0
|
2026-08-27 15:13:43 +02:00
|
|
|
|
|
|
|
|
|
|
class _MockQDialog(_MockWidget):
|
|
|
|
|
|
DialogCode = type("DialogCode", (), {"Accepted": DialogAccepted, "Rejected": 0})
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._layout = None
|
|
|
|
|
|
def setWindowTitle(self, title: str) -> None: pass
|
|
|
|
|
|
def setWindowIcon(self, icon) -> None: pass
|
|
|
|
|
|
def exec(self) -> int: return DialogAccepted
|
|
|
|
|
|
def exec_(self) -> int: return DialogAccepted
|
|
|
|
|
|
def accept(self) -> None: pass
|
|
|
|
|
|
def reject(self) -> None: pass
|
|
|
|
|
|
def resize(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def adjustSize(self) -> None: pass
|
|
|
|
|
|
def sizeHint(self):
|
|
|
|
|
|
return type("Size", (), {"width": lambda self=None: 200, "height": lambda self=None: 100})()
|
|
|
|
|
|
|
|
|
|
|
|
QDialog = _MockQDialog
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQDialogButtonBox(_MockWidget):
|
|
|
|
|
|
StandardButton = type("StandardButton", (), {"Ok": 1, "Cancel": 2})
|
|
|
|
|
|
Ok = 1
|
|
|
|
|
|
Cancel = 2
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self.accepted = type('Signal', (), {'connect': lambda s, cb: None})()
|
|
|
|
|
|
self.rejected = type('Signal', (), {'connect': lambda s, cb: None})()
|
|
|
|
|
|
|
|
|
|
|
|
QDialogButtonBox = _MockQDialogButtonBox
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQListWidgetItem:
|
|
|
|
|
|
def __init__(self, text: str = ""):
|
|
|
|
|
|
self._text = text
|
|
|
|
|
|
self._selected = False
|
|
|
|
|
|
def setSelected(self, value: bool) -> None: self._selected = value
|
|
|
|
|
|
def isSelected(self) -> bool: return self._selected
|
|
|
|
|
|
|
|
|
|
|
|
QListWidgetItem = _MockQListWidgetItem
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQListWidget(_MockWidget):
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._items = []
|
|
|
|
|
|
def addItem(self, item) -> None: self._items.append(item)
|
|
|
|
|
|
def item(self, index: int): return self._items[index] if 0 <= index < len(self._items) else None
|
|
|
|
|
|
def count(self) -> int: return len(self._items)
|
|
|
|
|
|
def row(self, item) -> int: return self._items.index(item) if item in self._items else -1
|
|
|
|
|
|
def selectedItems(self): return [i for i in self._items if i.isSelected()]
|
|
|
|
|
|
def setSelectionMode(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def sizeHintForRow(self, index: int) -> int: return 20
|
|
|
|
|
|
def setFixedHeight(self, height: int) -> None: pass
|
|
|
|
|
|
def frameWidth(self) -> int: return 1
|
|
|
|
|
|
|
|
|
|
|
|
QListWidget = _MockQListWidget
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQAbstractItemView:
|
|
|
|
|
|
SelectionMode = type("SelectionMode", (), {"ExtendedSelection": ExtendedSelection})
|
|
|
|
|
|
|
|
|
|
|
|
QAbstractItemView = _MockQAbstractItemView
|
|
|
|
|
|
|
2026-08-28 13:54:43 +02:00
|
|
|
|
class _MockQTableWidgetItem:
|
|
|
|
|
|
def __init__(self, text: str = ""):
|
|
|
|
|
|
self._text = text
|
|
|
|
|
|
def text(self) -> str: return self._text
|
|
|
|
|
|
def setText(self, text: str) -> None: self._text = text
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem = _MockQTableWidgetItem
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQTableWidget(_MockWidget):
|
|
|
|
|
|
def __init__(self, rows: int = 0, cols: int = 0, *args, **kwargs):
|
|
|
|
|
|
self._items = {}
|
|
|
|
|
|
self._row_count = rows
|
|
|
|
|
|
self._col_count = cols
|
|
|
|
|
|
self._hidden_rows = set()
|
|
|
|
|
|
def setItem(self, row: int, col: int, item) -> None: self._items[(row, col)] = item
|
|
|
|
|
|
def item(self, row: int, col: int): return self._items.get((row, col))
|
|
|
|
|
|
def rowCount(self) -> int: return self._row_count
|
|
|
|
|
|
def setRowCount(self, rows: int) -> None: self._row_count = rows
|
|
|
|
|
|
def setHorizontalHeaderLabels(self, labels) -> None: pass
|
|
|
|
|
|
def setSelectionMode(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def setSelectionBehavior(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def setEditTriggers(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def setSortingEnabled(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def setRowHidden(self, row: int, hidden: bool) -> None:
|
|
|
|
|
|
if hidden: self._hidden_rows.add(row)
|
|
|
|
|
|
else: self._hidden_rows.discard(row)
|
|
|
|
|
|
def isRowHidden(self, row: int) -> bool: return row in self._hidden_rows
|
|
|
|
|
|
def selectRow(self, row: int) -> None: pass
|
|
|
|
|
|
def selectedItems(self): return []
|
|
|
|
|
|
def setRangeSelected(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def sortByColumn(self, *args, **kwargs) -> None: pass
|
|
|
|
|
|
def resizeColumnToContents(self, col: int) -> None: pass
|
|
|
|
|
|
def setColumnWidth(self, col: int, width: int) -> None: pass
|
|
|
|
|
|
def columnWidth(self, col: int) -> int: return 100
|
|
|
|
|
|
def columnCount(self) -> int: return self._col_count
|
|
|
|
|
|
def verticalHeader(self): return _MockWidget()
|
|
|
|
|
|
def horizontalHeader(self): return _MockWidget()
|
|
|
|
|
|
def frameWidth(self) -> int: return 1
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidget = _MockQTableWidget
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQTableWidgetSelectionRange:
|
|
|
|
|
|
def __init__(self, *args, **kwargs): pass
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetSelectionRange = _MockQTableWidgetSelectionRange
|
|
|
|
|
|
|
2026-08-27 15:13:43 +02:00
|
|
|
|
class _MockQIcon:
|
|
|
|
|
|
def __init__(self, *args, **kwargs): pass
|
|
|
|
|
|
|
|
|
|
|
|
QIcon = _MockQIcon
|
|
|
|
|
|
|
2026-03-04 15:32:49 +01:00
|
|
|
|
def exec_dialog(dialog: Any) -> Any:
|
|
|
|
|
|
return YES
|
|
|
|
|
|
# --------------------------- TEST ---------------------------
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
debug_qt_status()
|