QGIS插件开发:如何实现动态添加字段重命名组合框?
QGIS插件动态添加字段重命名组的实现方案
需求可行性
完全可行,通过Qt的动态控件创建与布局管理就能实现该功能,以下是具体实现步骤:
步骤1:修改UI界面(Qt Designer)
- 在对话框UI中添加一个**"+"按钮**(命名为
addFieldPairBtn),用于触发添加新的字段重命名组。 - 创建垂直布局(如
QVBoxLayout,命名为fieldPairsLayout),将原有的mFieldComboBox和LKName组合框移入该布局,作为初始的一组重命名控件。
步骤2:修改Python代码逻辑
1. 初始化控件列表与绑定事件
在run方法的first_start分支中,添加按钮事件绑定并初始化存储组合框对的列表:
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = ReformatToLKNamesDialog() # 初始化存储字段重命名组的列表 self.field_pairs = [] # 将初始字段组加入列表 self.field_pairs.append( (self.dlg.mFieldComboBox, self.dlg.LKName) ) # Populate Richtlinien Combobox mit Richtliniennamen self.populateRichtinie() # Get value from Richtlinie self.selected_RL = self.dlg.Richtlinie.currentText() self.dlg.Richtlinie.currentTextChanged.connect(self.populateRLS19) # Update the combobox with the field names self.dlg.LayerName.layerChanged.connect(self.updateFields) # 绑定"+"按钮点击事件 self.dlg.addFieldPairBtn.clicked.connect(self.add_field_pair) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # 收集所有字段重命名映射 rename_mappings = {} for field_cb, lk_cb in self.field_pairs: original_field = field_cb.currentText() target_name = lk_cb.currentText() if original_field and target_name: rename_mappings[original_field] = target_name # 执行字段重命名逻辑 selected_layer = self.dlg.LayerName.currentLayer() if selected_layer and rename_mappings: with edit(selected_layer): for original, target in rename_mappings.items(): idx = selected_layer.fields().indexFromName(original) selected_layer.renameAttribute(idx, target) pass
2. 实现动态添加字段组的方法
添加add_field_pair方法,用于创建新的组合框并添加到布局:
def add_field_pair(self): # 创建新的"实际名称"组合框 new_field_cb = QgsFieldComboBox() # 绑定当前选中图层 selected_layer = self.dlg.LayerName.currentLayer() if selected_layer: new_field_cb.setLayer(selected_layer) # 创建新的"重命名为"组合框 new_lk_cb = QComboBox() # 加载当前政策的预设名称 self.populate_single_lk_combobox(new_lk_cb) # 用水平布局包裹一组两个组合框(保证同组控件在一行) h_layout = QHBoxLayout() h_layout.addWidget(new_field_cb) h_layout.addWidget(new_lk_cb) # 添加到垂直布局 self.dlg.fieldPairsLayout.addLayout(h_layout) # 将新组合框对加入列表 self.field_pairs.append( (new_field_cb, new_lk_cb) )
3. 调整现有方法支持多组合框更新
修改updateFields方法,更新所有"实际名称"组合框:
def updateFields(self): selectedLayer = self.dlg.LayerName.currentLayer() if selectedLayer: for field_cb, _ in self.field_pairs: field_cb.clear() field_cb.setLayer(selectedLayer)
修改populateRLS19方法,同时更新所有"重命名为"组合框,并拆分出单个组合框的加载方法:
def populateRLS19(self): selectedRichtlinie = self.dlg.Richtlinie.currentText() for _, lk_cb in self.field_pairs: self.populate_single_lk_combobox(lk_cb, selectedRichtlinie) def populate_single_lk_combobox(self, combobox, richtlinie=None): combobox.clear() if not richtlinie: richtlinie = self.dlg.Richtlinie.currentText() # 修正原代码键名不匹配问题 rlkurz = {'RLS-19':'sr', 'BUB':'ra', 'RLS-90':'la'} selctedRL_kurzel = rlkurz.get(richtlinie, '') if not selctedRL_kurzel: return rl_kuerzel = ['list', 'of', 'names'] # 替换为实际预设名称列表 rl_f = [selctedRL_kurzel + kuerzel for kuerzel in rl_kuerzel] combobox.addItems(rl_f)
注意事项
- 原代码中
rlkurz的键名与richtlinien列表不匹配,上述代码已修正该问题。 - 若需支持删除动态添加的组,可在创建每组时添加"-"按钮,绑定删除事件后从布局和列表中移除对应控件。
- QGIS中修改图层属性需在编辑模式下执行(使用
with edit(selected_layer):),这是标准操作流程。
内容的提问来源于stack exchange,提问作者i.i.k.
相关产品推荐
相关产品推荐

