GeoCat / qgis-bridge-plugin

GeoCat Bridge is a plugin for QGIS that can be used to publish geospatial (meta)data to the cloud.
https://www.geocat.net/bridge/
GNU General Public License v3.0
35 stars 19 forks source link

ModuleNotFoundError: No module named 'PyQt5.QtWebKitWidgets' #152

Open ajacque-trydea opened 1 year ago

ajacque-trydea commented 1 year ago

Describe the bug After updating to Python 3.10, geocatbridge does not start.

To Reproduce Steps to reproduce the behavior: Install the plugin or disable and enable it

Expected behavior No error launched

Screenshots Screenshot_20221117_150220

Environment info (please complete the following information):

Additional context Add any other relevant context about the problem here.

GeoSander commented 1 year ago

Hi @ajacque-trydea, thanks for reporting. Could you please describe how you updated your Python environment? I'm also not familiar with QGIS on Manjaro.

GeoSander commented 1 year ago

Also, please provide the full stack trace.

ajacque-trydea commented 1 year ago

I updated Python using manjaro standard package manager (yay). I also removed python2 on the same time (but I think qgis used python3). I tried to install an old version of PyQt5 as suggested here : Stackoverflow Cannot import QtWebKitWidgets in PyQt5 but a dependancy can't be found. I also tried to remove all QtWebKitWidget mentions from the plugin source code and packaged it as ZIP but I have the same problem on an other level. I'm not familiar with Python so, my install can be the problem cause

pip list result PyQt5 5.15.7 PyQt5-sip 12.11.0 PyQtWebEngine 5.15.6 PyQtWebEngine-Qt5 5.15.2

Full stack : ModuleNotFoundError: No module named 'PyQt5.QtWebKitWidgets' Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 423, in _startPlugin plugins[packageName] = package.classFactory(iface) File "/home/ajacque/.local/share/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/init.py", line 4, in classFactory from .plugin import GeocatBridge File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 888, in _import mod = _builtin_import(name, globals, locals, fromlist, level) File "/home/ajacque/.local/share/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/plugin.py", line 15, in from geocatbridge.ui.bridgedialog import BridgeDialog File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 888, in _import mod = _builtin_import(name, globals, locals, fromlist, level) File "/home/ajacque/.local/share/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/ui/bridgedialog.py", line 7, in from geocatbridge.ui.geocatwidget import GeoCatWidget File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 888, in _import mod = _builtin_import(name, globals, locals, fromlist, level) File "/home/ajacque/.local/share/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/ui/geocatwidget.py", line 5, in from qgis.PyQt.QtWebKitWidgets import QWebPage File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 888, in _import mod = _builtin_import(name, globals, locals, fromlist, level) File "/usr/lib/python3.10/site-packages/qgis/PyQt/QtWebKitWidgets.py", line 24, in from PyQt5.QtWebKitWidgets import * File "/usr/lib/python3.10/site-packages/qgis/utils.py", line 888, in _import mod = _builtin_import(name, globals, locals, fromlist, level) ModuleNotFoundError: No module named 'PyQt5.QtWebKitWidgets'

Version de Python : 3.10.8 (main, Nov 1 2022, 14:18:21) [GCC 12.2.0] Version de QGIS : 3.28.0-Firenze Firenze, exported

GeoSander commented 1 year ago

Hi @ajacque-trydea,

This will take some time to fix (I have not encountered the problem yet, but I am on 3.22 LTR still), because I will have to make 2 versions of geocatwidget.py: the current one that supports the old QtWebKitWidgets and a new one that supports QtWebEngineWidgets.

Since the issue is caused by a non-critical component of Bridge (the QWebView simply shows the "About" page), you can work around this crash by implementing the following steps:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>894</width>
    <height>557</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <property name="leftMargin">
    <number>0</number>
   </property>
   <property name="topMargin">
    <number>0</number>
   </property>
   <property name="rightMargin">
    <number>0</number>
   </property>
   <property name="bottomMargin">
    <number>0</number>
   </property>
   <item row="0" column="0">
    <widget class="QFrame" name="webFrame">
     <property name="sizePolicy">
      <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="frameShape">
      <enum>QFrame::StyledPanel</enum>
     </property>
     <property name="frameShadow">
      <enum>QFrame::Sunken</enum>
     </property>
     <layout class="QGridLayout" name="gridLayout_2">
      <property name="leftMargin">
       <number>0</number>
      </property>
      <property name="topMargin">
       <number>0</number>
      </property>
      <property name="rightMargin">
       <number>0</number>
      </property>
      <property name="bottomMargin">
       <number>0</number>
      </property>
      <property name="spacing">
       <number>0</number>
      </property>
     </layout>
    </widget>
   </item>
   <item row="1" column="0">
    <layout class="QHBoxLayout" name="horizontalLayout">
     <property name="leftMargin">
      <number>2</number>
     </property>
     <property name="bottomMargin">
      <number>0</number>
     </property>
     <item>
      <widget class="QLabel" name="txtInfo">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string/>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QDialogButtonBox" name="btnClose">
       <property name="sizePolicy">
        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="standardButtons">
        <set>QDialogButtonBox::Close</set>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

After this, you not should not have this issue anymore, and you will only see a gray area where the About page would otherwise have been.

Please let me know if the workaround works for you (and therefore others as well).

I'll follow up once this has been fixed properly.

GeoSander commented 1 year ago

PS: Could you please check if /usr/lib/python3.10/site-packages/qgis/PyQt/QtWebEngineWidgets.py exists on your machine by any chance? And if it doesn't, do the qgis and qgis/PyQt folders even exist in /usr/lib/python3.10/site-packages?

If none of them exist, then my workaround may not work. In that case, your Python upgrade may have messed with the path settings, so that QGIS is no longer able to find its own Python site packages. QGIS runs its own Python environment, so I don't think that Manjaro's package manager updates that?

ajacque-trydea commented 1 year ago

The workaround worked for me ! When I tried to correct it on myself, I didn't modify the .ui file.

The/usr/lib/python3.10/site-packages/qgis/PyQt/QtWebEngineWidgets.py does not exist on my dir but the qgis/PyQt exists. I think qgis got rid of the deprecated version of PyQt in its latest release.

GeoSander commented 1 year ago

Good to hear that the workaround helps preventing this issue.

Yes, if the qgis/PyQt dir is there, then it seems likely that the update removed it. I would like to do some more research on the matter.

If I have any updates I'll post them here. Closing for now.

categulario commented 1 week ago

I found this error in Qgis 3.38.2 distributed as a flatpak (installed in opensuse tumbleweed). The stack trace follows. I'm not sure if I can apply the suggested fix because the code has changed since and the mentioned file does not exist anymore. I tried editing geocatbridge/ui/geocatwidget.py commenting out where QtWebKitWidgets is imported without success.

I also saw the same error happening on a windows machine with latest qgis.

No se pudo cargar el complemento 'geocatbridge' debido a un error al llamar a su método classFactory() 

ImportError: cannot import name 'QtWebKitWidgets' from 'PyQt5' (/app/lib/python3.11/site-packages/PyQt5/__init__.py) 
Traceback (most recent call last):
  File "/app/share/qgis/python/qgis/utils.py", line 426, in _startPlugin
    plugins[packageName] = package.classFactory(iface)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/__init__.py", line 4, in classFactory
    from .plugin import GeocatBridge
  File "/app/share/qgis/python/qgis/utils.py", line 923, in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/plugin.py", line 15, in 
    from geocatbridge.ui.bridgedialog import BridgeDialog
  File "/app/share/qgis/python/qgis/utils.py", line 923, in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/ui/bridgedialog.py", line 7, in 
    from geocatbridge.ui.geocatwidget import GeoCatWidget
  File "/app/share/qgis/python/qgis/utils.py", line 923, in _import
    mod = _builtin_import(name, globals, locals, fromlist, level)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/ui/geocatwidget.py", line 9, in 
    WIDGET, BASE = gui.loadUiType(__file__)
                   ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins/geocatbridge/utils/gui.py", line 21, in loadUiType
    return uic.loadUiType(ui_file)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/share/qgis/python/qgis/PyQt/uic/__init__.py", line 36, in __loadUiType
    return __PyQtLoadUiType(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.11/site-packages/PyQt5/uic/__init__.py", line 207, in loadUiType
    exec(code_string.getvalue(), ui_globals)
  File "", line 68, in 
ImportError: cannot import name 'QtWebKitWidgets' from 'PyQt5' (/app/lib/python3.11/site-packages/PyQt5/__init__.py)

Versión de Python: 3.11.9 (main, Nov 10 2011, 15:00:00) [GCC 13.2.0] 
Versión de QGIS: 3.38.2-Grenoble Grenoble, exported 

Ruta de Python:
/app/share/qgis/python
/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python
/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python/plugins
/app/share/qgis/python/plugins
/usr/lib/python311.zip
/usr/lib/python3.11
/usr/lib/python3.11/lib-dynload
/app/lib/python3.11/site-packages
/usr/lib/python3.11/site-packages
/home/abraham/.var/app/org.qgis.qgis/data/QGIS/QGIS3/profiles/default/python
GeoSander commented 1 week ago

Seems that we have to put this on our top priority list, so re-opening.

Fixing this properly is not super easy (as you have discovered @categulario), but it should be doable. Will look into it a.s.a.p.

(Aside: I have installed QGIS LTR recently on a new Windows 11 machine and Bridge runs fine. This PyQt dependency stuff is super-complicated...)