Qt6中QSqlRelationalDelegate搭配QSqlRelationalTableModel修改单条外键记录问询
实现方案(Qt 6.2.1)
核心原理
QSqlRelationalDelegate 不依赖完整的QTableView/列表视图才能工作,它的核心能力是外键字段的显示值映射和关联表选项的编辑控件生成,单条记录编辑场景可以单独调用它的接口实现需求,不需要额外改造组件逻辑。
具体实现步骤
- 第一步:先构造对应业务表的
QSqlRelationalTableModel实例,和表格场景的配置完全一致,用setRelation()给外键字段绑定关联表映射,不需要把整个model绑定到视图,只需要用它来存储关联关系即可。
示例代码:
// 构造model,绑定要编辑的主表 auto *editModel = new QSqlRelationalTableModel(this, db); editModel->setTable("your_main_table"); // 配置外键关联,示例为第2列外键关联category表的id字段,显示name字段 editModel->setRelation(2, QSqlRelation("category", "id", "name")); editModel->select(); // 定位到需要编辑的单条记录,recordId为目标记录的主键值 int editRow = 0; for (; editRow < editModel->rowCount(); editRow++) { if (editModel->record(editRow).value("id").toInt() == recordId) break; }
- 第二步:构造
QSqlRelationalDelegate实例,不需要绑定到视图,直接在编辑窗口的对应外键输入位置,调用delegate的createEditor()生成关联选择下拉框,加到你的编辑表单布局中即可。
示例代码:
auto *delegate = new QSqlRelationalDelegate(this); // 获取外键字段对应的model索引,列号和第一步配置的外键列一致 QModelIndex relationIndex = editModel->index(editRow, 2); // 生成编辑控件,父对象设为编辑窗口的对应容器即可 QWidget *fkEditor = delegate->createEditor(ui->formContainer, QStyleOptionViewItem(), relationIndex); // 把生成的下拉框加到表单布局的对应位置 ui->formLayout->setWidget(2, QFormLayout::FieldRole, fkEditor); // 把当前记录的已有值填充到编辑器中 delegate->setEditorData(fkEditor, relationIndex);
- 第三步:保存数据时,调用delegate的
setModelData()把编辑器的值同步回model,delegate会自动把选中的显示值转换为对应的外键ID存储到主表,最后提交model修改即可完成保存。
示例代码:
// 提交外键字段的修改 delegate->setModelData(fkEditor, editModel, relationIndex); // 提交其他普通字段的修改 editModel->setData(editModel->index(editRow, 1), ui->titleEdit->text()); // 提交所有修改到数据库 editModel->submitAll();
注意事项
- 不需要构造额外的自定义请求,所有外键映射、数据提交都是通过
QSqlRelationalTableModel的原生数据库接口完成,确保数据库连接正常、关联表有查询权限即可。 - 如果编辑窗口不需要复用已有relation配置,也可以手动查询关联表的键值对填充下拉框,只是用
QSqlRelationalDelegate可以避免重复写关联查询逻辑,代码复用性更高。
内容的提问来源于stack exchange,提问作者MyNick
相关产品推荐
相关产品推荐

