Error when reloading new Plugin code in QGIS

278 Views Asked by At

I am nooby to Plugin Development but I'm trying to create a plugin in QGIS, for a Uni-subject, with its own graphical interface, which will receive a zipcode from the user and return the name of the corresponding location.

I already created the plugin skeleton, through the Plugin Builder and have designed the graphical interface with QtDesigner https://i.stack.imgur.com/h6k6Q.png . I also added the .txt file that contains the zipcodes database to the plugin folder as a resource.

From what I understand, the file to edit is the one that ends in dialog.py, through the init() method, in order to establish the connections between the signals emitted by the elements of the graphical interface and the corresponding callbacks.

However, when I change the code in the dialog.py and reload the plugin, it gives me an error, and when starting the QGIS it pop-ups an error message, and the plugin no longer appears. Error message after plugin reload

Could you give me some guidance here and maybe point me to where the problem could be? Thanks

The code is this one:

import os
import sys

import qgis.core
from qgis.PyQt import uic
from qgis.PyQt import (
QtCore,
QtWidgets
)

import geocoder

sys.path.append(os.path.dirname(__file__))
FORM_CLASS, _ = uic.loadUiType(
    os.path.join(
        os.path.dirname(__file__),
        "example_dialog_base.ui"
    ),
    resource_suffix=""
)

class ExampleDialog(QtWidgets.QDialog, FORM_CLASS):
    POSTAL_CODES_PATH = ":/plugins/example/todos_cp.txt"

    def __init__(self, parent=None):
    """Constructor."""
    super(ExampleDialog, self).__init__(parent)
    self.setupUi(self)
    # connect signals
    self.postal_code_le.textChanged.connect(self.toggle_find_button)
    self.find_code_btn.clicked.connect(self.execute)
    # set initial state
    self.find_code_btn.setEnabled(False)

    def toggle_find_button(self):
        if self.postal_code_le.text() == "":
            self.find_code_btn.setEnabled(False)
        else:
            self.find_code_btn.setEnabled(True)

    def execute(self):
        self.address_te.clear()
        try:
            raw_postal_code = self.postal_code_le.text()
            main_code, extension = validate_postal_code(raw_postal_code)
            record = self.find_record(main_code, extension)
            place_name = record[3]
            self.address_te.setPlainText(place_name)
            if self.create_layer_chb.isChecked():
                self.handle_layer_creation(record)
        except (ValueError, RuntimeError) as err:
            self.show_error(str(err))

    def find_record(self, main_code, extension):
        file_handler = QtCore.QFile(self.POSTAL_CODES_PATH)
        file_handler.open(QtCore.QIODevice.ReadOnly)
        stream = QtCore.QTextStream(file_handler)
        while not stream.atEnd():
            line = stream.readLine()
            info = line.split(";")
            code1 = info[-3]
            code2 = info[-2]
            if code1 == main_code and code2 == extension:
                result = info
                break
        else:
            raise RuntimeError("Sem resultados")
        return result

    def handle_layer_creation(self, record):
        place_name = record[3]
        point = geocode_place_name(place_name)
        print("lon: {} - lat: {}".format(point.x(), point.y()))
        layer = create_point_layer(
            point,
            f"found_location_for_{record[-3]}_{record[-2]}",
            place_name
        )
        current_project = qgis.core.QgsProject.instance()
        current_project.addMapLayer(layer)

    def show_error(self, message):
        message_bar = self.iface.messageBar()
        message_bar.pushMessage("Error", message, level=message_bar.Critical)

    def validate_postal_code(raw_postal_code):
        code1, code2 = raw_postal_code.partition("-")[::2]
        if code1 == "" or code2 == "":
            raise ValueError(
                "Incorrect postal code: {!r}".format(raw_postal_code))
        return code1, code2

    def geocode_place_name(place_name):
        geocoder_object = geocoder.osm(place_name)
        lon = geocoder_object.json.get("lng")
        lat = geocoder_object.json.get("lat")
        if lat is None or lon is None:
            raise RuntimeError(
                "Could not retrieve lon/lat for "
                "place: {!r}".format(place_name)
            )
        point = qgis.core.QgsPointXY(lon, lat)
        return point

        def create_point_layer(point, layer_name, place_name):
            layer = qgis.core.QgsVectorLayer(
                "Point?crs=epsg:4326&field=address:string(100)",
                layer_name,
                "memory"
            )
            provider = layer.dataProvider()
            geometry = qgis.core.QgsGeometry.fromPointXY(point)
            feature = qgis.core.QgsFeature()
            feature.setGeometry(geometry)
            feature.setAttributes([place_name])
            provider.addFeatures([feature])
            layer.updateExtents()
        return layer
0

There are 0 best solutions below