2

I'm creating a QGIS plugin that will load specific layers from our server, so inexperienced GIS users (e.g., upper management) can access key, up-to-date, layers with single clicks. I've created the plugin using "Plugin Builder" and QT designer. I have defined one main function that loads a vector layer (from a specified location) and applies a style file (from a specified location), called loadVector. Ideally, I want to pass loadVector the paths of the .shp and style file when the pushbuttons are clicked.

Below is a the dialog.py where there is one pushbutton "pb_BRLakes" that is to load a .shp from a GDB and apply a style path using the loadVector function.

import os
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
from qgis.core import *

# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'datalink_dialog_base.ui'))


class DataLinkDialog(QtWidgets.QDialog, FORM_CLASS):

    def __init__(self, parent=None):
        """Constructor."""
        super(DataLinkDialog, self).__init__(parent)
        # Set up the user interface from Designer through FORM_CLASS.
        # After self.setupUi() you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.pb_BRLakes.clicked.connect(lambda: loadVector("T:/Vancouver_Technical/","BackRiverRegion/GIS_Products/ESRI_GDB/NU_Topographic.gdb|layername=BR_TOP_HYD_ln_076GLakeswithNames","BackRiver Lakes","C:/Users/daniel.coutts/Desktop/ShapeFiles/test/WaterBodyStyleFile.qml"))

    def loadVector(drivePath,filePath,fileName,stylePath):
        layer = QgsVectorLayer(drivePath+filePath,fileName)
        QgsProject.instance().addMapLayer(layer)
        layer.loadNamedStyle(stylePath)
        layer.triggerRepaint()

I have tried many different options, and thought a lambda function would be the way to go, but I'm still running into issues.

3
  • 3
    What errors occur during code execution? Aug 9, 2022 at 17:08
  • The error I get is "NameError: name 'loadVector' is not defined". This includes having self in the method definition. I have gotten it to work for both rasters and vectors by including the paths in the function and calling "self.pushButton.clicked.connect(self.loadVector)", but this creates a huge number of functions for the toolbar. Passing the file paths in function call would be much more elegant.
    – Dan Coutts
    Aug 9, 2022 at 23:32
  • Please use the edit button beneath your question to revise it with any requested clarifications.
    – PolyGeo
    Aug 10, 2022 at 23:06

1 Answer 1

4

Add self to the line where you both define and call loadVector function.

    ....
    #                                       vvvv
    self.pb_BRLakes.clicked.connect(lambda: self.loadVector("T:/Vancouver_Technical/",...))

#              vvvv
def loadVector(self, drivePath, filePath, fileName, stylePath):
    ....
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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