簡體   English   中英

QCombo框設置圖層(適用於Python QGIS插件)

[英]QCombo box to set layer (for Python QGIS plugin)

我正在嘗試創建一個函數來根據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()

以您在面值上發布的示例代碼,我可以看到幾個問題。

首先,根據initGuirun方法之間的差異來判斷,可能有兩組組合框正在使用中。 信號連接到self.dlg.ui.*Combo ,而項目被添加到self.dlg.*Combo

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

第三,您似乎沒有保留組合框索引與列表之間的一對一關系,因為您正在根據類型過濾圖層。

最后,圖層列表來自地圖的值,所以肯定不能保證它們會以相同的順序出現。

我建議你將圖層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()

感謝@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)

這解決了我所擁有的多個組合框選擇混合和不正確的索引的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM