用于设置图层的 QCombo 框(用于 Python QGIS 插件) [英] QCombo box to set layer (for Python QGIS plugin)
问题描述
我正在尝试创建一个函数来根据 QComboBox 中选择的项目声明变量.它用于 QGIS 2.0 和 2.2 的插件.我收到列表索引超出范围"错误,但不知道为什么.我想知道我的 combobox.currentIndex() 是否没有给我我的想法.如果是这种情况,我想知道我是否应该在程序运行之前找到一种方法将组合框的索引设置为默认值.
I'm attempting to create a function to declare a variable in terms of an item chosen in a QComboBox. It's for a plugin for QGIS 2.0 and 2.2. I'm getting a "list index out of range" error, but cannot see why. I'm wondering if my combobox.currentIndex() isn't giving me what I think it is. If this is the case, I wonder if I should find a way set the combo box's index to something by default before the program runs.
#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() 现在使用 identifiers 方法,run() 根据来自线程 http://lists.osgeo.org/pipermail/qgis-developer/2010-November/011505.html.然而,这两个领域仍然给我带来问题.前者为无类型对象没有属性mapLayer",后者为语法错误".
I've now made some changes to the code thanks to the near-answer below. layerChanged() now uses an identifiers method and run() adds layers to combo box differently based on ideas from thread http://lists.osgeo.org/pipermail/qgis-developer/2010-November/011505.html. Both areas still give me issues however. "None type object has no attribute mapLayer" for the former and "Syntax error" for the latter.
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()
推荐答案
以你贴出的示例代码为例,我可以看出几个问题.
Taking example code you posted at face-value, I can see several problems.
首先,从initGui
和run
方法的区别来看,可能有两组组合框在使用.信号连接到 self.dlg.ui.*Combo
,而项目添加到 self.dlg.*Combo
.
Firstly, judging by the differences between the initGui
and run
methods, there may be two sets of combo-boxes in use. The signals are connected to self.dlg.ui.*Combo
, whereas the items are added to self.dlg.*Combo
.
其次,您似乎在没有事先清除它们的情况下一遍又一遍地填充组合框.
Secondly, you seem to be populating the combo-boxes over and over again without clearing them beforehand.
第三,您似乎没有保留组合框索引和列表之间的一对一关系,因为您正在根据类型过滤图层.
Thirdly, you do not seem to be preserving a one-to-one relationship between the combo-box indexes and the list, because you are filtering the layers based on type.
最后,图层列表来自地图的值,所以肯定不能保证它们会以相同的顺序出现.
And finally, the list of layers comes from the values of a map, so surely there is no guarantee that they will come out in the same order.
我建议您将 layer id 与每个组合项相关联,然后检索通过 mapLayer 方法创建图层.也就是说,添加这样的组合项:
I would suggest you associate a layer id with each combo item, and then retrieve the layer via the mapLayer method. That is, add the combo items like this:
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
,因此您需要像这样提取标识符:
NB: if you're using Python2, the combo data will be stored as a QVariant
so you would need to extract the identifier like this:
identifier = self.dlg.ui.indivCombo.itemData(index).toString()
或者这个:
identifier = self.dlg.ui.indivCombo.itemData(index).toPyObject()
这篇关于用于设置图层的 QCombo 框(用于 Python QGIS 插件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!