PyQt6:QSqlRelationalDelegate切换国家时自动选中首个关联城市
实现思路与代码修改
完全可以实现这个需求,核心是监听国家列的变更事件,当用户选择国家后,自动获取该国家下的首个城市ID并更新到城市列,同时确保城市下拉框打开时默认选中这个城市。
步骤1:修复现有SQL注入风险(可选但重要)
你当前代码里直接拼接SQL字符串存在注入风险,建议改用参数绑定:
q = QSqlQuery() q.prepare("SELECT id FROM country WHERE name = :name LIMIT 1") q.bindValue(":name", country_name) q.exec_()
步骤2:监听国家列的变更,自动更新城市列
重写commitData方法,在用户确认国家选择后,立即更新对应行的城市值:
def commitData(self, editor): # 先调用父类方法提交数据 super(MyQSqlRelationalDelegate, self).commitData(editor) # 获取当前编辑的索引 index = self.parent().currentIndex() if not index.isValid(): return # 判断是否是国家列(假设国家列是索引2) if index.column() == 2: model = index.model() row = index.row() # 获取选中的国家名称 country_name = model.data(index) if not country_name: # 清空城市列 model.setData(model.index(row, 3), "") return # 查询该国家的首个城市ID q = QSqlQuery() q.prepare(""" SELECT city.id FROM city JOIN country ON city.country_id = country.id WHERE country.name = :name ORDER BY city.name LIMIT 1 """) q.bindValue(":name", country_name) q.exec_() if q.next(): city_id = q.value(0) # 更新城市列的数值为首个城市ID model.setData(model.index(row, 3), city_id)
步骤3:确保城市下拉框默认选中首个城市
在现有setEditorData方法的过滤逻辑后,添加选中第一个选项的代码:
def setEditorData(self, editor, index): model = index.model() childModel = (model.relationModel(index.column()) if model is not None else None) if index.column() == 3 and childModel is not None: # City country_name = model.index(index.row(),2).data() if country_name is None or country_name == '': childModel.setFilter('') else: q = QSqlQuery() q.prepare("SELECT id FROM country where name=:name limit 1") q.bindValue(":name", country_name) q.exec_() country_id = None while q.next(): country_id = q.value(0) if country_id is not None: childModel.setFilter('country_id=' + str(country_id)) # 过滤后选中第一个选项 if childModel.rowCount() > 0: editor.setCurrentIndex(0) super(MyQSqlRelationalDelegate, self).setEditorData(editor, index)
补充说明
- 若使用
QTableView,需确保视图设置了合适的编辑触发方式(比如setEditTriggers(QTableView.DoubleClicked))。 - 若希望国家选择后实时更新城市(无需等待编辑提交),可监听编辑器的
currentIndexChanged信号触发更新,但要注意避免循环触发问题。
内容的提问来源于stack exchange,提问作者Minas Lyrakis
相关产品推荐
相关产品推荐

