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

QML中插入多列行及树形模型列填充异常问题求助

解决QStandardItemModel树形模型在QML TreeView中多列填充异常的问题

咱们先拆解下你代码里的核心问题,然后一步步修正:

问题根源分析

  1. 多余的树形结构成员:你在TreeModel里手动维护了child_items和parent_item,但QStandardItemModel本身已经通过QStandardItem的父子关系实现了树形管理,这些变量完全是画蛇添足,还会造成逻辑混淆。
  2. 未设置模型列数:你没有给模型指定columnCount,默认列数是1,导致插入的多列数据无法被TreeView正确识别。
  3. 对行/列数据的误解:你创建了三个独立的QStandardItem作为一行的三列,但没有明确绑定列与角色的对应关系,TreeView无法正确映射每个列要显示的角色数据。

分步修正方案

1. 简化TreeModel头文件

删掉多余的成员变量,让模型完全依赖QStandardItemModel的内置树形管理:

// treemodel.h
#include <QStandardItemModel>

class TreeModel : public QStandardItemModel {
    Q_OBJECT
public:
    explicit TreeModel(QObject *parent = nullptr);

private:
    static const int DisplayName;
    static const int DisplayInfo;
    static const int DisplayId;
};

2. 修正模型构造逻辑

设置正确的列数,并且为每行的每个列绑定对应角色的数据:

// treemodel.cpp
#include "treemodel.h"
#include <QStandardItem>

const int TreeModel::DisplayName = Qt::UserRole + 1;
const int TreeModel::DisplayInfo = Qt::UserRole + 2;
const int TreeModel::DisplayId = Qt::UserRole + 3;

TreeModel::TreeModel(QObject *parent) : QStandardItemModel(parent) {
    // 关键:设置模型列数为3,对应TreeView的三列
    setColumnCount(3);

    // 注册自定义角色名称,和QML中的role对应
    QHash<int, QByteArray> roles = roleNames();
    roles.insert(DisplayName, "A");
    roles.insert(DisplayInfo, "B");
    roles.insert(DisplayId, "C");
    setItemRoleNames(roles);

    QStandardItem *rootItem = invisibleRootItem();

    // 创建一行的三个列Item,每个Item绑定对应角色的数据
    QStandardItem *col1 = new QStandardItem();
    col1->setData("Sudip", DisplayName);
    QStandardItem *col2 = new QStandardItem();
    col2->setData("Ghimire", DisplayInfo);
    QStandardItem *col3 = new QStandardItem();
    col3->setData("Bahadur", DisplayId);

    // 将这一行插入根节点
    rootItem->appendRow({col1, col2, col3});

    // 可选:添加子节点演示树形结构
    QStandardItem *childCol1 = new QStandardItem();
    childCol1->setData("Child Sudip", DisplayName);
    QStandardItem *childCol2 = new QStandardItem();
    childCol2->setData("Child Ghimire", DisplayInfo);
    QStandardItem *childCol3 = new QStandardItem();
    childCol3->setData("Child Bahadur", DisplayId);
    col1->appendRow({childCol1, childCol2, childCol3});
}

3. 优化QML的TreeView配置

清理混乱的控件导入,确保窗口宽度足够容纳三列,并且列的角色与模型完全匹配:

// main.qml
import QtQuick 2.12
import QtQuick.Controls 1.4
import QtQuick.Window 2.12

Window {
    visible: true
    width: 950 // 调整宽度避免列被截断
    height: 480
    title: qsTr("Tree View Example")

    TreeView{
        id: tree_view
        anchors.fill: parent
        model: TreeModel
        sortIndicatorVisible: true
        alternatingRowColors: false
        backgroundVisible: false

        TableViewColumn{
            role: "A"
            title: "Elements"
            width: 300
        }
        TableViewColumn{
            role: "B"
            title: "more"
            width: 300
        }
        TableViewColumn{
            role: "C"
            title: "I am some title"
            width: 300
        }
    }
}

4. main.cpp保持不变

你的上下文属性设置是正确的,无需修改:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "treemodel.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    TreeModel t_model;
    engine.rootContext()->setContextProperty("TreeModel", &t_model);

    const QUrl url(u"qrc:/main.qml"_qs);
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

关键知识点总结

  • QStandardItemModel的树形结构是通过QStandardItem的父子关系实现的,不需要手动维护子项列表。
  • 必须设置columnCount,否则模型默认只会识别1列,多列数据无法显示。
  • TreeView的TableViewColumn的role属性必须和模型中注册的角色名称完全对应,才能正确获取并显示数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:47:46