Home > Software engineering >  Reducing redundant code for a PyQt application
Reducing redundant code for a PyQt application

Time:11-21

I'm not yet articulate enough to be specific with my title but that's basically the problem. I'm making a QGIS plugin with PyQt.

SCRIPT

class CreateSomething(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(CreateSomething, self).__init__(parent)
        self.setupUi(self)

        # Only select polygon layers in the layer combo box
        self.cmbLyrSelect.setFilters(QgsMapLayerProxyModel.PolygonLayer)
        # Emits a signal and connects to a function when layer is changed    
        self.cmbLyrSelect.layerChanged.connect(self.getLayerInfo)  

    # Function to get layer info if layer changed
    def getLayerInfo(self):
        # Selected/current layer in the combo box  
        currLyr = self.cmbLyrSelect.currentLayer()
        # Gets layer centroid
        lyrLoc = self.cmbLyrSelect.currentLayer().sourceExtent().center().toString(3)
        # Writes layer centroid to line edit
        self.linLyrLoc.setText(str(lyrLoc))
        # Populates combo box with fields of current layer
        self.cmbLyrFields.setLayer(currLyr)

If the plugin is opened the first time, it will not have the necessary widgets filled because the cmbLyrSelect widget only emits a signal when the user changes a layer.

First open

enter image description here

If layer is changed

enter image description here

WORKAROUND - duplicate the code in the getLayerInfo method to the __init__ method so that the widgets are filled up once the plugin starts.

class CreateSomething(QtWidgets.QDialog, FORM_CLASS):
        def __init__(self, parent=None):
            """Constructor."""
            super(CreateSomething, self).__init__(parent)
            self.setupUi(self)

            self.cmbLyrSelect.setFilters(QgsMapLayerProxyModel.PolygonLayer)    
            self.cmbLyrSelect.layerChanged.connect(self.getLayerInfo)    
            currLyr = self.cmbLyrSelect.currentLayer()
            lyrLoc = self.cmbLyrSelect.currentLayer().sourceExtent().center().toString(3)
            self.linLyrLoc.setText(str(lyrLoc))
            self.cmbLyrFields.setLayer(currLyr)

CodePudding user response:

Just call getLayerInfo once explicitly in __init__ before registering the LayerChanged callback:

def __init__(self, parent=None):
    """Constructor."""
    super(CreateSomething, self).__init__(parent)
    self.setupUi(self)

    # Only select polygon layers in the layer combo box
    self.cmbLyrSelect.setFilters(QgsMapLayerProxyModel.PolygonLayer)
    # Explicitly get layer info on init
    self.getLayerInfo()
    # Emits a signal and connects to a function when layer is changed    
    self.cmbLyrSelect.layerChanged.connect(self.getLayerInfo)  
  • Related