1

I am in the process of building a standalone interface to QGIS to use the processing functions. In essence I am creating a mainWindow GUI with a Qgsmapcanvas. The GUI also includes some user inputs that feed into the algorithm parameters. So far I have had success in creating and running the GUI, map canvass and running the algorithms, however all separately. In the process of compiling the three I seem to be missing the processingRegistry files and as a result when I run an algorithm it can't find it in the registry (as it is empty).

The code snippet imports and loads everything, initializes the processing, runs the UI with the intention of pushing a 'run' button to execute the algorithm. My issue is it cannot find the algorithm. I have scattered 'printing the registry' throughout the code to see whats inside it at key points.

After the Processing.initialize() the full list of algorithms will be available but when it is queried within the class.execute_model() appears to be empty. My initial thoughts and i think it revolves around my limited understanding of classes:

  1. my execute_model function needs to be outside the class and call the function from within the class?
  2. I need to somehow pass the registry info into the class?
  3. I've tried putting the Processing.Initialize() within the class but that doesn't appear to work either.

My code:

import time
from qgis.core import *
from qgis.core import QgsApplication
from qgis.gui import *
from PyQt5.QtCore import *
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow
from PyQt5.uic import loadUi
from PyQt5.QtGui import *
from qgis.analysis import QgsNativeAlgorithms

# run QGIS Application
QgsApplication.setPrefixPath("C:/OSGeo4W64/apps/qgis", True)
app1 = QgsApplication([], True)
app1.initQgis()

# Run Process Application
import sys
sys.path.append("C:/OSGeo4W64/apps/qgis/python/plugins")  # Folder where Processing is located
import processing
from processing.core.Processing import Processing
Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
for alg in QgsApplication.processingRegistry().algorithms():
    print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
from processing.tools import *

time.sleep(20)
# canvas_layers = []
# canvas = QgsMapCanvas()
# outputs = []

class IDC_Site_Selector(QMainWindow):

    def __init__(self):
        super(IDC_Site_Selector, self).__init__()
        loadUi("C:/IDCSS/IDCSSGUIv1.ui", self)
        self.setWindowTitle('IDC Site Selector v1')

        # check registry files
        for alg in QgsApplication.processingRegistry().algorithms():
            print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
        #time.sleep(20)

        self.pushButtonRunModel.clicked.connect(self.execute_model)

    @pyqtSlot()
    def execute_model(self):
        results = {}

        # check registry files
        for alg in QgsApplication.processingRegistry().algorithms():
            print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
        #time.sleep(20)

        # Load Master Files (to be replaced with a comboBox for LGA's in the future
        lots = ("C:/IDCSS/Model Data/Blacktown/Lot.shp")
        cadastre = QgsVectorLayer(lots, "vector", "ogr")

        # Add Lot Area Hectares
        alg_params = {
            'FIELD_LENGTH': 10,
            'FIELD_NAME': 'Lot_Area_Ha',
            'FIELD_PRECISION': 3,
            'FIELD_TYPE': 0,
            'FORMULA': ' $Area/10000',
            'INPUT': cadastre,
            'NEW_FIELD': True,
            'OUTPUT': "C:/IDCSS/Model Data/Blacktown/Lot_Area.shp"
        }
        feedback = QgsProcessingFeedback()
        results['LotArea'] = processing.run('qgis:fieldcalculator', alg_params, feedback=feedback)


app = QApplication(sys.argv)
widget = IDC_Site_Selector()
widget.show()
sys.exit(app.exec_())

0

The functions need to be called within __main__ program rather than before. Not 100% sure, but I believe by not doing this the Processing.initialise() values were lost/overwritten prior to executing the class. If anyone is able to explain or edit my answer as to why this is the case I would be greatly appreciative.

Amended Code Portion

if __name__ == '__main__':
    app = QApplication(sys.argv)

    QgsApplication.setPrefixPath("C:/OSGeo4W64/apps/qgis", True)
    app1 = QgsApplication([], True)
    app1.initQgis()

    app2 = Processing()
    test3 = app2.initialize()
    # check registry files
    for alg in QgsApplication.processingRegistry().algorithms():
        print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
    time.sleep(20)

    widget = IDC_Site_Selector()
    widget.show()
    sys.exit(app.exec_())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.