QCombobox设置图层(适用于Python QGIS插件)

时间:2014-04-09 19:59:08

标签: python pyqt4 qgis qcombobox

我尝试创建一个函数来根据QComboBox中选择的项声明变量。它适用于QGIS 2.0和2.2的插件。我的"列表索引超出范围"错误,但不明白为什么。我想知道我的combobox.currentIndex()是不是给了我我认为的东西。如果是这种情况,我想知道在程序运行之前我是否应该找到一种方法将组合框的索引设置为默认值。

#connecting the combo boxes to function
def initGui(self):
    QObject.connect(self.dlg.ui.indivCombo,SIGNAL("currentIndexChanged(int)"),self.layerChanged)
    QObject.connect(self.dlg.ui.grosCombo,SIGNAL("currentIndexChanged(int)"),self.layerChanged)
    QObject.connect(self.dlg.ui.resCombo,SIGNAL("currentIndexChanged(int)"),self.layerChanged)

#function to set my layer parameter to the equal the item at index chosen
def layerChanged(self):
    self.layerMap = QgsMapLayerRegistry.instance().mapLayers().values()
    self.indivLayer = self.layerMap[self.dlg.ui.indivCombo.currentIndex()]
    self.grosLayer = self.layerMap[self.dlg.ui.grosCombo.currentIndex()]
    self.resLayer = self.layerMap[self.dlg.ui.resCombo.currentIndex()]

#populating combo box with layers in stack
def run(self):
    # show the dialog
    self.dlg.show()
    for layer in self.iface.legendInterface().layers():
        if layer.type() == QgsMapLayer.VectorLayer:
            self.dlg.indivCombo.addItem(layer.name())
            self.dlg.grosCombo.addItem(layer.name())
            self.dlg.resCombo.addItem(layer.name())
    # Run the dialog event loop
    result = self.dlg.exec_()
    # See if OK was pressed
    if result == 1:
        pass

由于下面的答案,我现在对代码进行了一些更改。 layerChanged()现在使用标识符方法,run()根据线程http://lists.osgeo.org/pipermail/qgis-developer/2010-November/011505.html中的想法以不同方式向组合框添加图层。然而,这两个领域仍然给我提问。 "没有类型对象没有属性mapLayer"对于前者和"语法错误"对于后者。

def layerChanged(self, index):
    #globals previously initialized as None
    global registry, indivID, grosID, resID
    registry = QgsMapLayerRegistry.instance()
    indivID = self.dlg.ui.indivCombo.data(index).toPyObject()
    grosID = self.dlg.ui.grosCombo.data(index).toPyObject()
    resID = self.dlg.ui.resCombo.data(index).toPyObject()
    self.indivLayer = registry.mapLayer(indivID)
    self.grosLayer = registry.mapLayer(grosID)
    self.resLayer = registry.mapLayer(resID)

def calculatelength(self):
    global registry, resID
    self.resLayer = registry.mapLayer(resID)
    idx = self.resLayer.fieldNameIndex('Length')
    #code continues

 def run(self):

    # show the dialog
    self.dlg.show()
    for layer in self.iface.legendInterface().layers():
        if layer.type() == QgsMapLayer.VectorLayer:
            self.dlg.ui.indivCombo.addItem(layer.name(),QVariant(layer.id())
            self.dlg.ui.grosCombo.addItem(layer.name(),QVariant(layer.id())
            self.dlg.ui.resCombo.addItem(layer.name(),QVariant(layer.id())
    # Run the dialog event loop
    result = self.dlg.exec_()
    # See if OK was pressed
    if result == 1:
        pass
        #AEPStats()

2 个答案:

答案 0 :(得分:1)

以您在面值上发布的示例代码,我可以看到几个问题。

首先,根据initGuirun方法之间的差异判断,可能有两组组合框正在使用中。信号连接到self.dlg.ui.*Combo,而项目则添加到self.dlg.*Combo

其次,你似乎一遍又一遍地填充组合框而不事先清除它们。

第三,你似乎没有保留组合框索引和列表之间的一对一关系,因为你是根据类型过滤图层。

最后,图层列表来自地图的值,所以肯定不能保证它们会以相同的顺序出现。

我建议您将layer id与每个组合项相关联,然后通过mapLayer方法检索图层。也就是说,添加如下组合项:

    self.dlg.indivCombo.addItem(layer.name(), layer.id())

然后像这样检索图层:

def layerChanged(self, index):
    registry = QgsMapLayerRegistry.instance()
    identifier = self.dlg.ui.indivCombo.itemData(index)
    self.indivLayer = registry.mapLayer(identifier)

注意:如果您使用的是Python2,则组合数据将存储为QVariant,因此您需要提取如下标识符:

    identifier = self.dlg.ui.indivCombo.itemData(index).toString()

或者这个:

    identifier = self.dlg.ui.indivCombo.itemData(index).toPyObject()

答案 1 :(得分:1)

感谢@ekhumoro的帮助,现在可行了。只有对回答的建议所做的更改才在layerChanged():

def layerChanged(self):
    registry = QgsMapLayerRegistry.instance()
    identifier = str(self.dlg.ui.indivCombo.itemData(self.dlg.ui.indivCombo.currentIndex()))
    self.indivLayer = registry.mapLayer(identifier)

这解决了我所选择的多个组合框混淆和不正确的索引问题。