3

I got another issue writing a plugin to convert three shape files into an .obs input file. I created a UI (Qt) with a QComboBox to select a layer (that works fine). As soon as one of the layers in the QComboBox is selected, a second ComboBox should be filled with the fields of the layer to select from. To do that I'm trying to call a function, that is to be called, as soon, as a layer is selected in the first ComboBox. Unfortuntelly that does not work. Here is what I tried:

First I wrote a function to fill the second ComboBox with the field names:

  def build_Layer_Index_Changed():
    QMessageBox.information(None, "DEBUG", "Build Layer routine called. :)")
    canvas = self.iface.mapCanvas()
    dlg2 = ShowDialog2() 
    build = canvas.layer(int(dlg2.Sel_Build_Layer.currentIndex()))
    if int(dlg2.Sel_Build_Layer.currentIndex()) >= 0:
      if not build.geomTypeDict == 2:   # Types: 0:"point",1:"line",2:"polygon", Buildings layer has to be of type 2
        QMessageBox.critical(self.iface.mainWindow(), ":-/ Selected buillding layer is not of type vector(polygon)! :-/" ) 
      else:
        build_fields = self.getFields(build)
        dlg2.Sel_buildhight_field.clear()
        dlg2.Sel_buildhight_field.addItems(build_fields)

"dlg2.Sel_buildhight_field" is the second QComboBox. I tried to connect it to the first ComboBox's (dlg2.Sel_Build_Layer) Signal by

QtCore.QObject.connect(dlg2.Sel_Build_Layer, QtCore.SIGNAL("currentIndexChanged"), self.build_Layer_Index_Changed())

but I get an error: "TypeError: build_Layer_Index_Changed() takes no arguments (1 given)". If I remove the brackets after self.build_Layer_Index_Changed, I get no eror, but the function is not called (as the MessageBox doesn't appear. I thought I did it exactly as given in the Example at http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots, but obviously I'm doing something wrong…

3 Answers 3

2

Try this:

dlg2.Sel_Build_Layer.currentIndexChanged.connect(self.build_Layer_Index_Changed)

Also the reason you are getting the error is because build_Layer_Index_Changed() doesn't take instance as it's first arg e.g. self. you need to have:

def build_Layer_Index_Changed(self):
1
  • I would also suggest watching/reading up on how Python works so you understand when/where you need to have self and brackets
    – Nathan W
    Oct 16, 2012 at 11:52
1

Try this while connecting: currentIndexChanged function pass 1 argument i.e is changed index and while defining build_Layer_Index_Changed pass two arguments (self, index).

QtCore.QObject.connect(dlg2.Sel_Build_Layer,
                       QtCore.SIGNAL("currentIndexChanged(int)"),
                       self.build_Layer_Index_Changed())
0

After reading lots of tutorials and documantation, i changed my function to the following, which I think works (I was not able to run it yet due to another bug…).

def build_Layer_Index_Changed(self, canvas, dlg2, index):
    QMessageBox.information(None, "DEBUG", str("Build Layer routine called. :). Current Index = " + str(dlg2.Sel_Build_Layer.currentIndex()) + str(canvas) + str(dlg2) + str(build) + str(index)))
    if index >= 0:
        build = canvas.layer(index)
        try:
          build_fields = self.getFields(build)
        except:
          QMessageBox.critical(None, "Check selected layer!", ":-/ Faild to load buildings layer! (Index changed routine):-/" )
        dlg2.Sel_buildhight_field.clear()
        dlg2.Sel_buildhight_field.addItems(build_fields)

I call the function by

dlg2.Sel_Build_Layer.activated[int].connect(self.build_Layer_Index_Changed(canvas, dlg2))

which looks much more understandable to me than the C++like approach (Many thanks to Nathan!).

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.