1

I am a pyqgis user and I am trying to create a QGIS plugin where that plugin have two tabs widgets and two combo box where first combo box have a list from layers and second combo box have list of fields for current layer in combo box one.

That combo box is inside in tab widget two, and I want to to activate any time user start plugin.

My code works but not correctly - I have curious results.

In the first way in my _ init _ the combo box 1 work fine every time to start the user the plugin then combo box 1 activate correct, but the combo box 2 insert only six fields for some layers (that layers have many fields 19).

In the second way combo box 1 and combo box 2 work fine have correct list of layers and fields, but to activate combo box 1 must be the user to move some layers in panel and after this activate. I don't want this .

Where I have wrong ?

Who is correct signal activate for combo box 1 ?

Maybe some signal to activate when the user press tab 2 from tab widget?

in _ _init __ :

#first way
registry = QgsMapLayerRegistry.instance()
registry.layersAdded.connect(self.change_layers)
#second way
self.iface.legendInterface().groupRelationsChanged.connect(self.change_layers)

#field change
self.ui.comboBox_2.currentIndexChanged.connect(self.updateFields)

layer function :

def change_layers(self):
   self.ui.comboBox_2.clear()
   legendInterface = self.iface.legendInterface()
   listLayerName = [i.name() for i in legendInterface.layers() if i.type() == QgsMapLayer.VectorLayer]
   # add all these layer names to combo box comboLayerList
   self.ui.comboBox_2.addItems(listLayerName)

field function :

    def layer_field(self):
        self.mapCanvas.refresh()
        layers = self.iface.legendInterface().layers()
        # Identify selected layer by its index
        selectedLayerIndex = self.ui.comboBox_2.currentIndex()
        print selectedLayerIndex
        selectedLayer = layers[selectedLayerIndex]
        # Identify fields of the selected layer
        fields = selectedLayer.pendingFields()
        # Get field names of the fields
        fieldnames = [field.name() for field in fields]
        # Clear comboBox_5
        self.ui.comboBox_3.clear()
        # Add field names to comboBox_5
        self.ui.comboBox_3.addItems(fieldnames)
1
  • 2
    Don't code your own combo boxes - use QgsMapLayerComboBox and QgsFieldComboBox instead -- you're just making more work for yourself!
    – ndawson
    Jan 30, 2018 at 20:38

1 Answer 1

3

When user select layer in comboBox1, you could use combo.changeCurrentIndex.connect to trigger function in cascade and load fields name to comboBox2.

Example :

def updateFields(self):
   fields_array = []
   layers = self.iface.legendInterface().layers()
   layer_name = self.ui.comboBox_1.currentText()
   for layer in layers:
       if el.name() == layer_name: # find layer from combo text
           fields = layer.dataProvider().fields() # get fields
           fields_array= [fields.name() for field in fields]    
   return self.ui.comboBox_2.addItems(fields_array) # populate combo

self.ui.comboBox_1.currentIndexChanged.connect(self.updateFields) # on select
3
  • thank I ue this trigger but not work again,any other idea ? Jan 30, 2018 at 18:16
  • the currentIndexChanged have in _ init _ must be out of _ init _ ? Jan 30, 2018 at 20:00
  • Could you update all of your code now please ? When you said "not work again" you had just 6 results in fields combo or any fields are loaded into combo ?
    – Gaet
    Jan 30, 2018 at 23:31

Your Answer

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

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