3

I'm writing a plugin, I want to change the content of a comboBox (fields) depending of the content of another comboBox (layers).

My plugin is a dockwidget. I can populate the fields comboBox just starting the plugin in the def run(self): function, and it's working fine:

        layerNom = self.dockwidget.comboBoxErrores.currentText()#Get the text value of the comboBox
        for lyr in QgsMapLayerRegistry.instance().mapLayers().values():    #Get layers        
            if lyr.name()==str(layerNom): 
                fields = lyr.pendingFields() #Get Fiels
                field_names = [field.name() for field in fields] #Field List
                self.dockwidget.comboCampos.addItems(field_names) #Added to the comboBox

But when I try to update the content of the fields comboBox I really don't know how to do it.

In my "pluginName_dockwidget.py" file, in the init function I have created the connection with the function that will repopulate the comboBox with the new content:

self.comboBoxErrores.currentIndexChanged['QString'].connect(self.pueblaCampos)

In the same file I have a function that get the value of the layer name of the comboBox and emit it with the signal created previously:

sennalComboIndex = pyqtSignal(str)
.
.
.
def pueblaCampos(self):      

    layerName = self.comboBoxErrores.currentText()
    self.sennalComboIndex.emit(layerName)

In my main file, I have the rest of the function:

def pueblaCampos(self, layerName):        

    for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
        if lyr.name()==str(layerName):
            fields = lyr.pendingFields()
            field_names = [field.name() for field in fields]             
            self.dockwidget.comboCampos.clear()
            self.dockwidget.comboCampos.addItems(field_names)

When I change the slected item in the layers comboBox, nothing happens. What Am I missing?

4
  • Are you calling the .connect signal in __init__() or initGui() function?
    – artwork21
    Commented Mar 7, 2016 at 12:48
  • from __init__()
    – Luismi
    Commented Mar 7, 2016 at 14:42
  • 1
    Try putting your .connect statements in the initGui() function instead to see if the signal is heard.
    – artwork21
    Commented Mar 7, 2016 at 17:26
  • Thanks a lot for your suggestion, it was the only step I needed to make it run!!
    – Luismi
    Commented Mar 7, 2016 at 19:59

3 Answers 3

2

As I noted in my comment, add your .connect statements to the initGui() function. This will allow the signal to be heard on whatever connect event.

2

If you are programming in PyQGIS you should use QgsMapLayerComboBox and QgsFieldComboBox objects. It's easier and direct. For example, the next snipped code (from my plugin):

.
.
.
    def __init__(self, iface):
.
.
.
        okBtn = self.dlg.okButton
        okBtn.connect(okBtn, SIGNAL("clicked()"), self.my_function)

        self.wcbL = QgsMapLayerComboBox(self.dlg)
        self.wcbL.move(150,28)
        self.wcbL.setMinimumWidth(203)
        self.wcbL.setFilters(QgsMapLayerProxyModel.VectorLayer)

        self.wcbF = QgsFieldComboBox(self.dlg)
        self.wcbF.move(150,68)
        self.wcbF.setMinimumWidth(203)
.
.
.
    def select_layer_fields(self, vlayer):

        self.wcbF.setLayer(vlayer)
        field = self.wcbF.setLayer(vlayer)

    def my_function(self):

        vlayer = self.wcbL.currentLayer()
        field = self.wcbF.currentText()
        print field

    def run(self):
        """Run method that performs all the real work"""
        vlayer = self.wcbL.currentLayer()
        self.wcbF.setLayer(vlayer)
        self.wcbL.layerChanged.connect(self.select_layer_fields)

        # show the dialog
        self.dlg.show()
.
.
.

it can do the work. I tried out with the following three vector layers:

enter image description here

After selecting polygon8 vector layer, you can observe that the fields from its attributes table are the same that into the QgsFieldComboBox object.

enter image description here

After selecting polygon5 vector layer, the fields automatically change to show those of this new layer; as it can be observed in the next image:

enter image description here

To corroborate that it works well, the slot my_function (connected to OK button) has an instruction to print the reference of the fields at the Python Console of QGIS after clicking the OK button. It could be observed for fields 'area' and 'values' of polygon8 at the next image:

enter image description here

1
  • thank you very much for your complete and useful answer!! I'm going to try it as an alternative!
    – Luismi
    Commented Mar 7, 2016 at 20:09
0

In order to clear what I did, I'm going to reply myself. I just needed a line that connect the signal emited from the pluginName_dockwidget.py file to pluginName.py in the initGui() function.

this is the line:

self.dockwidget.sennalComboIndex.connect(self.pueblaCampos)

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.