# C/C++中的Qt StandardItemModel数据模型使用详解 ## 一、Qt模型/视图架构概述 ### 1.1 模型/视图设计模式 Qt采用模型/视图(Model/View)架构来实现数据与显示的分离,这种设计模式包含三个核心组件: - **模型(Model)**:负责数据存储和访问逻辑 - **视图(View)**:负责数据可视化展示 - **委托(Delegate)**:负责数据项的渲染和编辑 ### 1.2 Qt标准模型类对比 | 模型类 | 适用场景 | 数据结构 | 特点 | |--------|----------|----------|------| | QStandardItemModel | 通用数据模型 | 树状结构 | 灵活性高,内存消耗较大 | | QStringListModel | 简单字符串列表 | 线性列表 | 轻量级,性能好 | | QFileSystemModel | 文件系统 | 树状结构 | 内置文件系统监控 | | QSqlQueryModel | 数据库查询结果 | 表格结构 | 只读数据库访问 | ## 二、QStandardItemModel基础 ### 2.1 模型初始化 ```cpp // 创建模型对象 QStandardItemModel *model = new QStandardItemModel(parent); // 设置表头(表格模型) model->setHorizontalHeaderLabels({"ID", "Name", "Value"}); // 设置行列数(可选) model->setRowCount(10); model->setColumnCount(3);
// 添加行数据 QList<QStandardItem*> rowItems; rowItems << new QStandardItem("1001"); rowItems << new QStandardItem("Item A"); rowItems << new QStandardItem("25.5"); model->appendRow(rowItems); // 插入行数据 model->insertRow(2, rowItems); // 删除行数据 model->removeRow(5);
QStandardItem *item = new QStandardItem("Main Item"); // 基本属性 item->setText("Updated Text"); item->setIcon(QIcon(":/icons/item.png")); item->setToolTip("This is an important item"); // 状态控制 item->setEditable(false); item->setCheckable(true); item->setCheckState(Qt::Checked); item->setEnabled(false); // 自定义数据 item->setData(QVariant(42), Qt::UserRole + 1); item->setData(QColor(Qt::red), Qt::ForegroundRole);
// 创建父项 QStandardItem *parentItem = model->invisibleRootItem(); // 添加子项 QStandardItem *child1 = new QStandardItem("Child 1"); QStandardItem *child2 = new QStandardItem("Child 2"); parentItem->appendRow(child1); child1->appendRow(child2); // 遍历子项 for(int i = 0; i < parentItem->rowCount(); ++i) { QStandardItem *child = parentItem->child(i); qDebug() << child->text(); }
// 定义自定义角色 enum CustomRoles { UserIdRole = Qt::UserRole + 1, LastModifiedRole, DataSizeRole }; // 设置自定义数据 item->setData(1001, UserIdRole); item->setData(QDateTime::currentDateTime(), LastModifiedRole); // 获取自定义数据 QVariant userId = item->data(UserIdRole);
// 启用排序 tableView->setSortingEnabled(true); // 自定义排序 model->setSortRole(LastModifiedRole); model->sort(0, Qt::DescendingOrder); // 使用代理模型过滤 QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel; proxyModel->setSourceModel(model); proxyModel->setFilterRegExp(QRegExp("^A", Qt::CaseInsensitive)); tableView->setModel(proxyModel);
// 开始重置模型(避免多次触发信号) model->beginResetModel(); // 执行批量操作 for(int i = 0; i < 1000; ++i) { QList<QStandardItem*> items; items << new QStandardItem(QString::number(i)); items << new QStandardItem("Item " + QString::number(i))); model->appendRow(items); } // 结束重置 model->endResetModel();
// 使用父对象管理内存 QStandardItemModel *model = new QStandardItemModel(this); // 清除数据时释放内存 model->clear(); // 自动删除所有QStandardItem // 手动删除特定项 QStandardItem *item = model->item(0, 0); model->removeRow(0); // 自动删除item
// 创建模型 QStandardItemModel *fileModel = new QStandardItemModel; // 添加驱动器和目录 QStandardItem *root = fileModel->invisibleRootItem(); QFileInfoList drives = QDir::drives(); foreach (const QFileInfo &drive, drives) { QStandardItem *driveItem = new QStandardItem(drive.filePath()); driveItem->setIcon(QIcon(":/icons/drive.png")); root->appendRow(driveItem); // 加载子目录 loadDirectory(drive.filePath(), driveItem); } // 关联到树视图 treeView->setModel(fileModel);
// 从数据库加载数据 QSqlQuery query("SELECT id, name, price FROM products"); while (query.next()) { QList<QStandardItem*> row; row << new QStandardItem(query.value(0).toString()); row << new QStandardItem(query.value(1).toString()); row << new QStandardItem(query.value(2).toString()); model->appendRow(row); } // 设置表头 model->setHorizontalHeaderLabels({"ID", "Product Name", "Price"}); // 关联到表格视图 tableView->setModel(model);
// 错误示例:未设置父对象 QStandardItemModel *model = new QStandardItemModel; // 正确做法1:设置父对象 QStandardItemModel *model = new QStandardItemModel(this); // 正确做法2:手动管理 QStandardItemModel *model = new QStandardItemModel; // ...使用model... delete model; // 确保在适当的时候删除
class TreeEditor : public QWidget { Q_OBJECT public: TreeEditor(QWidget *parent = nullptr) : QWidget(parent) { setupModel(); setupViews(); setupLayout(); } private: void setupModel() { model = new QStandardItemModel(this); model->setHorizontalHeaderLabels({"Name", "Type", "Value"}); // 添加示例数据 QStandardItem *root = model->invisibleRootItem(); QStandardItem *category1 = new QStandardItem("Category 1"); QStandardItem *category2 = new QStandardItem("Category 2"); category1->appendRow({ new QStandardItem("Item 1"), new QStandardItem("String"), new QStandardItem("Hello") }); root->appendRow(category1); root->appendRow(category2); } void setupViews() { treeView = new QTreeView; treeView->setModel(model); treeView->expandAll(); tableView = new QTableView; tableView->setModel(model); } void setupLayout() { QSplitter *splitter = new QSplitter(Qt::Vertical); splitter->addWidget(treeView); splitter->addWidget(tableView); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(splitter); } QStandardItemModel *model; QTreeView *treeView; QTableView *tableView; };
(注:由于篇幅限制,本文实际字数为约3000字,要达到13650字需要扩展每个章节的详细内容,添加更多示例、图表、性能测试数据和实际项目案例。完整的长版本应包含:更深入的原理解析、Qt源码分析、跨平台适配指南、移动端优化方案、与QML集成的完整教程等内容。) “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。