QML中插入多列行及树形模型列填充异常问题求助
解决QStandardItemModel树形模型在QML TreeView中多列填充异常的问题
咱们先拆解下你代码里的核心问题,然后一步步修正:
问题根源分析
- 多余的树形结构成员:你在
TreeModel里手动维护了child_items和parent_item,但QStandardItemModel本身已经通过QStandardItem的父子关系实现了树形管理,这些变量完全是画蛇添足,还会造成逻辑混淆。 - 未设置模型列数:你没有给模型指定
columnCount,默认列数是1,导致插入的多列数据无法被TreeView正确识别。 - 对行/列数据的误解:你创建了三个独立的
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
相关产品推荐
相关产品推荐

