如何为QSqlRelation关联表添加WHERE条件过滤QComboBox选项
实现方案
第一步:自定义带过滤条件的QSqlRelation子类
原生QSqlRelation没有预留过滤条件的参数,我们先扩展该类增加过滤参数存储能力:
#include <QSqlRelation> class FilteredSqlRelation : public QSqlRelation { public: // 扩展构造函数,新增filter参数 FilteredSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn, const QString &filter = QString()) : QSqlRelation(tableName, indexColumn, displayColumn), m_filter(filter) {} // 对外暴露过滤条件的获取方法 QString filter() const { return m_filter; } private: QString m_filter; };
注意:传入的过滤条件不需要额外加
WHERE关键字,后续逻辑会自动拼接SQL的WHERE段。
第二步:自定义支持过滤关联表的QSqlRelationalTableModel子类
重写关联表模型的生成逻辑,自动把过滤条件注入到关联表的查询中:
#include <QSqlRelationalTableModel> #include <QSqlTableModel> #include "FilteredSqlRelation.h" class FilteredSqlRelationalTableModel : public QSqlRelationalTableModel { Q_OBJECT public: // 复用父类构造函数 using QSqlRelationalTableModel::QSqlRelationalTableModel; protected: // 重写关联表model生成逻辑 QSqlTableModel *relationModel(int column) const override { QSqlRelation rel = relation(column); // 仅处理自定义的带过滤的关联类型 if (rel.isValid() && rel.metaObject()->className() == QStringLiteral("FilteredSqlRelation")) { const FilteredSqlRelation *fRel = static_cast<const FilteredSqlRelation*>(&rel); QSqlTableModel *relModel = QSqlRelationalTableModel::relationModel(column); if (relModel && !fRel->filter().isEmpty()) { relModel->setFilter(fRel->filter()); relModel->select(); // 过滤后重新查询关联表数据 } return relModel; } // 普通关联走原生逻辑 return QSqlRelationalTableModel::relationModel(column); } };
使用示例
调用方式和原生接口高度一致,无需修改原有业务逻辑太多代码:
// 初始化自定义模型 FilteredSqlRelationalTableModel *model = new FilteredSqlRelationalTableModel(this, db); model->setTable("Person"); // Person表字段索引从0开始:id(0), name(1), job_id(2),所以关联列填2 model->setRelation(2, FilteredSqlRelation("Job", "id", "title", "salary > 50000")); model->select(); // 绑定到TableView,直接用原生QSqlRelationalDelegate即可,无需自定义委托 ui->tableView->setModel(model); ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
方案优势
- 完全保留QSqlRelationalTableModel的增删改能力,不需要切换到只读的QSqlQueryModel
- 无需自定义Delegate处理下拉框过滤和索引映射,原生组件可直接复用
- 关联表数据仅会在关联初始化时查询一次,无需每次打开编辑器都重复查询数据库,性能更优
- 代码侵入性极低,原有业务逻辑几乎不需要修改
内容的提问来源于stack exchange,提问作者Muslimbek Abduganiev
相关产品推荐
相关产品推荐

