4 votos

Las macros de Python no funcionan en QGIS

Quiero ejecutar una macro Python con QGIS 3.22.14 y python39 instalado mediante OSGEO4W y windows 11 home. El propósito es ejecutar un script automáticamente cuando abro un proyecto en QGIS.el problema con la macro Python siempre ocurre, incluso con otros scripts excepto cuando no trabajo con vector. El ejemplo sirve solo para mostrar el problema. Los errores pueden cambiar, pero siempre se da la misma situación. El código funciona en la consola o en la versión independiente, pero el código no funciona como macros Python.

Este es mi script que funciona correctamente cuando lo ejecuto en la consola Python de QGIS:

uri = "pagingEnabled='true' restrictToRequestBBOX='1' srsname='EPSG:2056' typename='ac_001_1_v1_1_disponibilita_catasto_rdpp' url='https://wfs.geo.ti.ch/?MAP=/project/wfs_ac.qgz' version='auto'"
catasto = QgsVectorLayer(uri, "ac_001_1_v1_1_disponibilita_catasto_rdpp", "WFS")
QgsProject.instance().addMapLayer(catasto)

Ejecuto el MISMO script en la macro: enter image description here

El resultado es que: enter image description here

Así que decidí ejecutar la versión independiente del código de trabajo en la consola que ha prooven para trabajar con un archivo por lotes. Puse todo el código bajo def openProject().

El guión es el siguiente:

def openProject():
    from qgis.core import *
    # Supply path to qgis install location
    QgsApplication.setPrefixPath("C:/OSGeo4W/apps/qgis-ltr", True)

    # Create a reference to the QgsApplication.  Setting the
    # second argument to False disables the GUI.
    qgs = QgsApplication([], False)

    # Load providers
    qgs.initQgis()

    # Write your code here to load some layers, use processing
    # algorithms, etc.

    from qgis.analysis import QgsNativeAlgorithms
    import processing
    from processing.core.Processing import Processing
    Processing.initialize()*
    QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())

    uri = "pagingEnabled='true' restrictToRequestBBOX='1' srsname='EPSG:2056' typename='ac_001_1_v1_1_disponibilita_catasto_rdpp' url='https://wfs.geo.ti.ch/?MAP=/project/wfs_ac.qgz' version='auto'"
    catasto = QgsVectorLayer(uri, "ac_001_1_v1_1_disponibilita_catasto_rdpp", "WFS")
    QgsProject.instance().addMapLayer(catasto)
    # Finally, exitQgis() is called to remove the
    # provider and layer registries from memory
    qgs.exitQgis()

def saveProject():
    pass

def closeProject():
    pass

Muestro el script mencionado incluso como imagen: enter image description here

El resultado: enter image description here

¿Cómo resolver este problema?

Tal vez la solución debe ser el uso de la secuencia de comandos independiente y la comprensión de qué módulo para agregar en lugar de *, que no es aceptada en la función.

5voto

Hoppe Puntos 13

Este código funciona desde la consola de Python 3.10.4 en QGIS 3.26.2-Buenos Aires:

from urllib.parse import urlencode
from qgis.core import QgsVectorLayer, QgsProject

base_url = 'https://wfs.geo.ti.ch/?'
params = {
    "MAP": "/project/wfs_ac.qgz",
    "pagingEnabled": 'true',
    "restrictToRequestBBOX": '1',
    "srsname": 'EPSG:2056',
    "typename": 'ac_001_1_v1_1_disponibilita_catasto_rdpp',
    "version": 'auto',
}

uri = base_url + urlencode(params)
catasto = QgsVectorLayer(
    uri,
    "ac_001_1_v1_1_disponibilita_catasto_rdpp",
    "WFS",
)
QgsProject.instance().addMapLayer(catasto)

Así que cuando se incrusta en una macro, debe tener este aspecto:

from urllib.parse import urlencode
from qgis.core import (
    QgsVectorLayer,
    QgsProject,
)
from qgis.analysis import QgsNativeAlgorithms
import processing
from processing.core.Processing import Processing

def openProject():
    base_url = "https://wfs.geo.ti.ch/?"
    params = {
        "MAP": "/project/wfs_ac.qgz",
        "pagingEnabled": "true",
        "restrictToRequestBBOX": "1",
        "srsname": "EPSG:2056",
        "typename": "ac_001_1_v1_1_disponibilita_catasto_rdpp",
        "version": "auto",
    }

    uri = base_url + urlencode(params)
    catasto = QgsVectorLayer(
        uri,
        "ac_001_1_v1_1_disponibilita_catasto_rdpp",
        "WFS",
    )
    QgsProject.instance().addMapLayer(catasto)

def saveProject():
    pass

def closeProject():
    pass

Por supuesto, las macros deben estar habilitadas para que ésta funcione. Si es necesario, ve a "Configuración > Opciones > General" para cambiar esta opción:

enter image description here

Por favor, ten en cuenta que esto puede suponer una brecha de seguridad si abres un archivo de proyecto que no es de confianza, de ahí esta advertencia cuando la opción está en "Preguntar":

enter image description here

Por último, sus características se cargarán al abrir su proyecto QGIS:

enter image description here

También me tomé la libertad de reescribir la forma de construir la URL para que fuera más flexible y pitónica. Esto se basa en urllib que es un módulo Python de la biblioteca estándar.

No es necesario instanciar el archivo QgsApplication si usted es ya utilizando la GUI, hacer esto puede conducir al siguiente error fatal:

QGIS died on signal 11Warning: QCoreApplication::arguments: 
  Please instantiate the QApplication object first
Segmentation fault (core dumped)

Si no es así, es posible que desee cambiar Processing.initialize()* a Processing.initialize() (error tipográfico).

Elimine también la línea from qgis.core import * .

Véase también: https://gis.stackexchange.com/a/279937/65370

Pero puedes utilizar directamente los algoritmos de procesamiento en función de lo que quieras conseguir.

Por lo tanto, te dejo que averigües cómo incrustar tu código restante en estos fragmentos, porque por tu pregunta, parece que aún no estás utilizando ninguno de los algoritmos de procesamiento.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X