You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在QSqlRelationalTableModel中刷新外键下拉列表

解决Qt 6.8.2中QSqlRelationalTableModel关联下拉列表不实时更新的问题

问题场景

基于Qt 6.8.2的SQLite桌面应用中,master表(含id、name字段)与details表(含id、idMaster、value字段)通过QSqlRelationalTableModel建立主从关联,details表的idMaster列通过QSqlRelationalDelegate显示为包含master表名称的下拉框。但增删master表行后,details表的下拉选项无法实时同步,需重启应用才生效,调用modelDetails->select()、setFilter()等方法均无效。

问题原因

QSqlRelationalDelegate使用的关联下拉模型(QSqlRelationModel)采用缓存机制,master表数据变更时,该缓存模型不会自动触发刷新,导致下拉选项停留在旧数据状态。

解决方案

通过监听master表模型的增删改信号,主动刷新details表关联列的下拉模型,实现实时同步。

步骤1:监听master表的变更信号

在初始化modelMaster后,添加信号连接,捕获master表的行插入、删除、数据修改事件:

// 初始化master模型后添加以下代码
connect(modelMaster, &QSqlTableModel::rowsInserted, this, [=]() {
    refreshDetailsRelationalCombo();
});
connect(modelMaster, &QSqlTableModel::rowsRemoved, this, [=]() {
    refreshDetailsRelationalCombo();
});
connect(modelMaster, &QSqlTableModel::dataChanged, this, [=]() {
    refreshDetailsRelationalCombo();
});

步骤2:实现下拉模型刷新函数

在主窗口类中添加成员函数refreshDetailsRelationalCombo,用于刷新details表关联列的下拉选项:

void YourMainWindow::refreshDetailsRelationalCombo() {
    // 获取details模型中idMaster列对应的关联模型
    QSqlRelationModel* relModel = modelDetails->relationModel(static_cast<int>(ColumnsDetails::MODEL_COL_ID_MASTER));
    if (relModel) {
        relModel->select(); // 重新查询master表,更新下拉选项
        // 强制视图刷新该列的委托显示
        ui->viewDetails->viewport()->update();
    }
}

关键说明

  • 无需重新调用modelDetails->setRelation(),直接刷新已存在的关联模型更高效;
  • dataChanged信号用于处理master表中name字段修改的场景,保证下拉选项的名称同步更新;
  • viewport()->update()强制视图刷新,确保下拉框立即显示最新选项。

修改后的完整代码片段

QSqlDatabase db = QSqlDatabase::database(DATABASE_NAME);

// setup Details model
modelDetails = new QSqlRelationalTableModel(this, db);
modelDetails->setTable(TABLE_DETAILS);
modelDetails->setRelation(static_cast<int>(ColumnsDetails::MODEL_COL_ID_MASTER), QSqlRelation("master", "id", "name"));
modelDetails->setEditStrategy(TableModel::OnRowChange);
modelDetails->select();
// setup Details QTableView
ui->viewDetails->setModel(modelDetails);
ui->viewDetails->setItemDelegate(new QSqlRelationalDelegate(ui->viewDetails));

// setup Master model
modelMaster = new QSqlRelationalTableModel(this, db);
modelMaster->setTable(TABLE_MASTER);
modelMaster->setEditStrategy(TableModel::OnRowChange);
modelMaster->select();
// setup Master QTableView
ui->viewMaster->setModel(modelMaster);
ui->viewMaster->setItemDelegate(new QSqlRelationalDelegate(ui->viewMaster));

// 新增:监听master表变更,同步details下拉选项
connect(modelMaster, &QSqlTableModel::rowsInserted, this, [=]() {
    refreshDetailsRelationalCombo();
});
connect(modelMaster, &QSqlTableModel::rowsRemoved, this, [=]() {
    refreshDetailsRelationalCombo();
});
connect(modelMaster, &QSqlTableModel::dataChanged, this, [=]() {
    refreshDetailsRelationalCombo();
});

// when the user selects a Master row, filter the Details table
connect(ui->tableMaster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, [=](const QModelIndex &current, const QModelIndex &previous)
{
    const QAbstractItemModel *model = current.model();
    QModelIndex indexMaster = model->index(current.row(), static_cast<int>(ColumnsMaster::MODEL_COL_ID));
    int idMaster = model->data(indexMaster).toInt();
    modelDetails->setFilter(QString("idMaster=%1").arg(idMaster)); // 修正原代码笔误:tableDetails改为modelDetails
});

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:12:08