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

如何通过QTreeView子项选择数据子集并在QTableView展示?

Qt模型/视图联动:点击QTreeView子项更新QTableView数据

我正在开发一个Qt模型/视图程序,需要实现点击QTreeView中的子项时,让QTableView显示对应的数据子集。作为领域新手,找不到匹配的示例,Qt文档的相关说明也不够清晰。

界面效果

我用QMap存储示例数据并填充模型,但不知道如何让树形视图与表格视图联动?如何让表格仅显示树形视图选中子项对应的数据?我了解到代理相关内容,但不确定是否适用于此场景,恳请给出指导。

目前我为树形视图和表格视图分别使用了一个模型,定义了两个QMap:

QMap<QString,QList<QString>> namesMap;
namesMap = {{"Parent #1", {"Child 1-1", "Child 1-2", "Child 1-3"}},
            {"Parent #2", {"Child 2-1", "Child 2-2"}},
            {"Parent #3", {"Child 3-1"}}};

QMap<QString,QList<QList<QString>>> dataMap;
dataMap = {{"Child 1-1", {{"Name 1", "00000000000000", "1-1"},{"Name 2", "00000000000000", ""}}},
           {"Child 1-2", {{"Name 1", "00000000000000", "1-2"},{"Name 2", "00000000000000", ""}}},
           {"Child 1-3", {{"Name 1", "00000000000000", "1-3"},{"Name 2", "00000000000000", ""}}},
           {"Child 2-1", {{"Name 1", "00000000000000", "2-1"},{"Name 2", "00000000000000", ""}}},
           {"Child 2-2", {{"Name 1", "00000000000000", "2-2"},{"Name 2", "00000000000000", ""}}},
           {"Child 3-1", {{"Name 1", "00000000000000", "3-1"},{"Name 2", "00000000000000", ""}}}};

以下是我设置模型的代码:

表格模型初始化

tableModel = new QStandardItemModel(3,3,this);

QMap<QString,QList<QList<QString>>>::iterator itr;
for (itr = dataMap.begin(); itr != dataMap.end(); ++itr)
{
    int row = 0;
    // 遍历QList
    QListIterator<QList<QString>> i(itr.value());
    while (i.hasNext())
    {
        QList list = i.next();
        for (int col = 0; col < list.size(); ++col)
        {
            QModelIndex index = tableModel->index(row, col, QModelIndex());
            tableModel->setData(index, list.at(col));
        }
        ++row;
    }
}

树形模型初始化

treeModel = new QStandardItemModel(this);

QStandardItem *root = treeModel->invisibleRootItem();
QList<QStandardItem*> rowItems;

QMap<QString,QList<QString>>::iterator iter;
for (iter = namesMap.begin(); iter != namesMap.end(); ++iter)
{
    QString parentName = QString(iter.key());
    QStandardItem *parent = new QStandardItem(parentName);
    parent->setEditable(false);
    rowItems << parent;
    root->appendRow(rowItems);
    rowItems.clear();

    QListIterator<QString> i(iter.value());
    while (i.hasNext())
    {
        QString childName = QString(i.next());
        QStandardItem *item = new QStandardItem(childName);
        item->setEditable(false);
        rowItems << item;
        parent->appendRow(rowItems);
        rowItems.clear();
    }
}

视图绑定模型

treeView = new QTreeView(this);
treeView->setModel(treeModel);

dataTable = new QTableView(this);
dataTable->setModel(tableModel);

解决方案

1. 核心思路:监听树形视图选中事件

代理主要用于自定义数据显示/编辑,你的场景无需使用代理,只需监听QTreeView的选中信号,触发表格模型的数据更新即可。

2. 具体实现步骤

步骤1:连接树形视图的点击信号

在视图初始化完成后,添加信号槽连接:

connect(treeView, &QTreeView::clicked, this, &YourWidgetClass::onTreeItemClicked);

步骤2:实现槽函数更新表格数据

void YourWidgetClass::onTreeItemClicked(const QModelIndex &index)
{
    // 仅处理子项(判断是否为父项的子节点)
    if (!index.parent().isValid()) {
        return; // 点击父项时不处理
    }

    QString childName = treeModel->data(index).toString();
    // 从dataMap中获取对应数据
    auto targetData = dataMap.value(childName);
    if (targetData.isEmpty()) {
        return;
    }

    // 清空表格模型并重置列数
    tableModel->clear();
    tableModel->setColumnCount(3);

    // 填充对应数据到表格
    int row = 0;
    for (const auto &rowData : targetData) {
        for (int col = 0; col < rowData.size(); ++col) {
            tableModel->setData(tableModel->index(row, col), rowData.at(col));
        }
        row++;
    }
}

步骤3:设置初始状态

程序启动时可默认选中第一个子项,触发表格数据初始化:

// 选中Parent #1下的第一个子项
QModelIndex firstChild = treeModel->index(0, 0, treeModel->index(0, 0));
treeView->setCurrentIndex(firstChild);
// 手动触发数据更新
onTreeItemClicked(firstChild);

3. 额外优化建议

  • 给树形子项添加自定义角色存储标识,避免依赖字符串匹配:
    创建子项时:
    QStandardItem *item = new QStandardItem(childName);
    item->setEditable(false);
    item->setData(childName, Qt::UserRole); // 存储唯一标识
    
    槽函数中获取标识:
    QString childName = index.data(Qt::UserRole).toString();
    
  • 若数据量较大,可提前将数据转换为QStandardItem结构缓存,减少每次点击的重复计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:44:53