jueves, 20 de diciembre de 2018

Adaptación de un plugin, de QGIS 2 a QGIS 3, para desplegar ráster values como tooltip

Una reserva que impide cambiar rápidamente desde QGIS 2 a QGIS 3 es la imposibilidad de adaptar en un tiempo perentorio todas aquellas aplicaciones, especialmente los plugin, que se han elaborado con Python 2. Hasta ahora, según mi experiencia, los desarrolladores de QGI3 han preservado prácticamente intactas la mayoría de las clases y, aunque numerosos, los cambios son proporcionalmente menores a lo que cabría esperar.

Para probar este aserto vamos a adaptar un plugin, de QGIS 2 a QGIS 3, para desplegar ráster values como tooltip que se encuentra disponible para descargar desde esta respuesta de gis.stackexchange.com. En la oferta de plantillas para Plugin Builder 3 sólo existen disponibles las correspondientes a "Tool button with dialog", "Tool button with dock widget" y "Processing Provider". El plugin a adaptar no se ajusta a ninguna de las categorías anteriores (podría catalogarse como un "Tool button with action") y es por ello que su escogencia se hizo con base en éste criterio.

Para activar este plugin en QGIS 2 se hace click sobre el icono respectivo cambiando el aspecto del icono a bajo relieve y el del cursor de "flecha" a "cruz". Para adaptar este plugin a QGIS 3 y recrear el comportamiento que tiene en QGIS 2 hay que considerar básicamente tres archivos: metadata.txt, test.py y __init__.py.

En metadata.txt basta con cambiar la línea que contiene qgisMinimumVersion; tal como se presenta a continuación:

qgisMinimumVersion=3.0

Esto hará que QGIS, a pesar de otros errores (aparecerá como roto e imposible de activar), deje de señalar que es incompatible con la versión 3 actual.

En test.py lo primero que hacemos es cambiar los módulos cargados por el plugin de:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.
.
.
# Import the PyQt and QGIS libraries
from qgis.core import QgsApplication, QgsRasterLayer, QgsRaster
from qgis.gui import QgsMapToolEmitPoint
from PyQt4.QtCore import QObject, SIGNAL, QTimer
from PyQt4.QtGui import ( QMessageBox, QIcon, QAction, QMenu, QActionGroup,
                          QWidgetAction, QToolTip )
.
.
.

a los siguientes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.
.
.
# Import the PyQt and QGIS libraries
from qgis.core import QgsApplication, QgsRasterLayer, QgsRaster
from qgis.gui import QgsMapToolEmitPoint
from PyQt5.QtCore import QObject, QTimer
from PyQt5.QtWidgets import ( QMessageBox, QAction, QMenu, QActionGroup,
                              QWidgetAction, QToolTip)
from PyQt5.QtGui import ( QIcon ).
.
.

Todas las clases de QGIS 2 tienen su equivalente con el mismo nombre en QGIS 3 excepto una: SIGNAL. Este módulo se usa para conectar slots en PyQt4 pero fue eliminado en PyQt5. Se usó el buscador de texto del editor para corroborar que nunca fue usado en el código original para tal fin. Por tanto, no hay de que preocuparse por ahora.

Al cargar el plugin con el Plugin Reloader ya se puede activar pero arroja el error de la imagen siguiente:


El método de classFactory() se invoca en __init__.py donde sólo hay que modificar la clase siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.
.
.
def classFactory(iface):
    # load Test class from file test.py
    from test import Test
    return Test(iface)
.
.
.

a esta otra:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.
.
.
def classFactory(iface):
    # load Test class from file test.py
    from .test import Test
    return Test(iface)
.
.
.

Cargado nuevamente el plugin con el Plugin Reloader, al ejecutarlo ya no arroja el error y funciona tal como se esperaba


No hay comentarios: