From 7a54e424cb12855423fcbbf760cf1ab785f83972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Bra=C3=B1a?= Date: Sun, 3 May 2026 01:15:16 +0200 Subject: [PATCH] =?UTF-8?q?Georeferencing:=20fallback=20modo=20manual=20cu?= =?UTF-8?q?ando=20QtWebEngine=20no=20est=C3=A1=20disponible=20(FreeCAD=20f?= =?UTF-8?q?latpak)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PVPlantGeoreferencing.py | 149 +++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 60 deletions(-) diff --git a/PVPlantGeoreferencing.py b/PVPlantGeoreferencing.py index 9a87c55..65eb531 100644 --- a/PVPlantGeoreferencing.py +++ b/PVPlantGeoreferencing.py @@ -58,40 +58,9 @@ class MapWindow(QtGui.QWidget): self.setupUi() def setupUi(self): - # Compatibilidad PySide6 / PySide2: QWebEngineView cambia de ubicación - QWebEngineView = None - QWebChannel = None - for modpath in [ - 'PySide6.QtWebEngineWidgets', # Qt6 temprano - 'PySide6.QtWebEngineCore', # Qt6 reciente: QWebEnginePage aquí - 'PySide6.QtWebEngineQuick', # Qt6 reciente: QWebEngineView aquí - 'PySide2.QtWebEngineWidgets', # Qt5 - 'PySide.QtWebEngineWidgets', # Qt5 alias - ]: - try: - parts = modpath.split('.') - mod = __import__(parts[0], fromlist=parts[1:]) - for p in parts[1:]: - mod = getattr(mod, p) - if hasattr(mod, 'QWebEngineView'): - QWebEngineView = mod.QWebEngineView - if hasattr(mod, 'QWebChannel'): - QWebChannel = mod.QWebChannel - break - except (ImportError, AttributeError): - continue - - if QWebEngineView is None: - # Fallback: QWebEnginePage + QWebEngineView desde QtWebEngineCore - try: - from PySide6.QtWebEngineCore import QWebEnginePage - from PySide6.QtWebEngineQuick import QWebEngineView - QWebEngineView = QWebEngineView - except ImportError: - FreeCAD.Console.PrintError( - "PVPlantGeoreferencing: No se encontró QtWebEngine. " - "Instala PySide6-QtWebEngine o usa una versión de FreeCAD con soporte web.\n") - return + # Intentar cargar QtWebEngine (no siempre disponible, ej: FreeCAD flatpak) + QWebEngineView, QWebChannel = self._load_webengine() + self._webengine_available = QWebEngineView is not None self.ui = FreeCADGui.PySideUic.loadUi(PVPlantResources.__dir__ + "/PVPlantGeoreferencing.ui", self) @@ -118,36 +87,54 @@ class MapWindow(QtGui.QWidget): self.layout.addWidget(RightWidget) # Left Widgets: - # -- Search Bar: - self.valueSearch = QtGui.QLineEdit(self) - self.valueSearch.setPlaceholderText("Search") - self.valueSearch.returnPressed.connect(self.onSearch) + if self._webengine_available: + # -- Search Bar: + self.valueSearch = QtGui.QLineEdit(self) + self.valueSearch.setPlaceholderText("Search") + self.valueSearch.returnPressed.connect(self.onSearch) - searchbutton = QtGui.QPushButton('Search') - searchbutton.setFixedWidth(80) - searchbutton.clicked.connect(self.onSearch) + searchbutton = QtGui.QPushButton('Search') + searchbutton.setFixedWidth(80) + searchbutton.clicked.connect(self.onSearch) - SearchBarLayout = QtGui.QHBoxLayout(self) - SearchBarLayout.addWidget(self.valueSearch) - SearchBarLayout.addWidget(searchbutton) - LeftLayout.addLayout(SearchBarLayout) + SearchBarLayout = QtGui.QHBoxLayout(self) + SearchBarLayout.addWidget(self.valueSearch) + SearchBarLayout.addWidget(searchbutton) + LeftLayout.addLayout(SearchBarLayout) - # -- Webbroser: - self.view = QWebEngineView() - self.channel = QWebChannel(self.view.page()) - self.view.page().setWebChannel(self.channel) - self.channel.registerObject("MyApp", self) - file = os.path.join(DirResources, "webs", "main.html") - self.view.page().loadFinished.connect(self.onLoadFinished) - self.view.page().load(QtCore.QUrl.fromLocalFile(file)) - LeftLayout.addWidget(self.view) - # self.layout.addWidget(self.view, 1, 0, 1, 3) + # -- Web browser: + self.view = QWebEngineView() + self.channel = QWebChannel(self.view.page()) + self.view.page().setWebChannel(self.channel) + self.channel.registerObject("MyApp", self) + file = os.path.join(DirResources, "webs", "main.html") + self.view.page().loadFinished.connect(self.onLoadFinished) + self.view.page().load(QtCore.QUrl.fromLocalFile(file)) + LeftLayout.addWidget(self.view) + else: + # -- Modo manual: entrada de coordenadas sin mapa web + self.valueSearch = QtGui.QLineEdit(self) + self.valueSearch.setPlaceholderText("Latitud, Longitud (ej: 40.4168, -3.7038)") + self.valueSearch.returnPressed.connect(self.onManualCoords) + + searchbutton = QtGui.QPushButton('Ir') + searchbutton.setFixedWidth(80) + searchbutton.clicked.connect(self.onManualCoords) + + SearchBarLayout = QtGui.QHBoxLayout(self) + SearchBarLayout.addWidget(self.valueSearch) + SearchBarLayout.addWidget(searchbutton) + LeftLayout.addLayout(SearchBarLayout) + + info = QtGui.QLabel("Mapa web no disponible. Introduce coordenadas manualmente.") + info.setStyleSheet("color: #888; font-style: italic; padding: 20px;") + info.setAlignment(QtCore.Qt.AlignCenter) + LeftLayout.addWidget(info) # -- Latitud y longitud: self.labelCoordinates = QtGui.QLabel() self.labelCoordinates.setFixedHeight(21) LeftLayout.addWidget(self.labelCoordinates) - # self.layout.addWidget(self.labelCoordinates, 2, 0, 1, 3) # Right Widgets: labelKMZ = QtGui.QLabel() @@ -171,9 +158,6 @@ class MapWindow(QtGui.QWidget): radio3 = QtGui.QRadioButton("Datos GPS") radio1.setChecked(True) - # buttonDialog = QtGui.QPushButton('...') - # buttonDialog.setEnabled(False) - vbox = QtGui.QVBoxLayout(self) vbox.addWidget(radio1) vbox.addWidget(radio2) @@ -181,7 +165,6 @@ class MapWindow(QtGui.QWidget): self.groupbox.setLayout(vbox) RightLayout.addWidget(self.groupbox) - # ------------------------ self.checkboxImportGis = QtGui.QCheckBox("Importar datos GIS") RightLayout.addWidget(self.checkboxImportGis) @@ -206,6 +189,52 @@ class MapWindow(QtGui.QWidget): with open(file, 'r') as f: frame.runJavaScript(f.read()) + def _load_webengine(self): + """Intenta cargar QWebEngineView desde cualquier versión de PySide. + Retorna (QWebEngineView_class, QWebChannel_class) o (None, None).""" + for modpath in [ + 'PySide6.QtWebEngineWidgets', + 'PySide6.QtWebEngineCore', + 'PySide6.QtWebEngineQuick', + 'PySide2.QtWebEngineWidgets', + 'PySide.QtWebEngineWidgets', + ]: + try: + parts = modpath.split('.') + mod = __import__(parts[0], fromlist=parts[1:]) + for p in parts[1:]: + mod = getattr(mod, p) + View = getattr(mod, 'QWebEngineView', None) + Channel = getattr(mod, 'QWebChannel', None) + if View is not None: + return View, Channel + except (ImportError, AttributeError): + continue + # Fallback: intentar por separado QtWebChannel (sí existe en flatpak) + try: + from PySide6.QtWebChannel import QWebChannel as Channel + except ImportError: + Channel = None + FreeCAD.Console.PrintWarning( + "PVPlantGeoreferencing: QtWebEngine no disponible. " + "Usando modo manual de coordenadas.\n") + return None, Channel + + def onManualCoords(self): + """Procesa entrada manual de latitud,longitud""" + text = self.valueSearch.text().strip() + if not text: + return + try: + parts = text.replace(',', ' ').split() + lat = float(parts[0]) + lon = float(parts[1]) + self.georeference_coordinates = {'lat': lat, 'lon': lon} + self.labelCoordinates.setText(f"{lat:.6f}, {lon:.6f}") + FreeCAD.Console.PrintMessage(f"Coordenadas: {lat:.6f}, {lon:.6f}\n") + except (ValueError, IndexError): + FreeCAD.Console.PrintError("Formato inválido. Usa: latitud, longitud\n") + def onSearch(self): if self.valueSearch.text() == "": return