QT对于列表和表格结构都有相应的model实现, 唯独对QTreeView没有提供任何默认实现,只能子类化QAbstractItemModel. 由于树形结构比较复杂,层次结构不固定,用MVC框架实现的确比较费劲. 还好QT提供的这个例子能够处理很多通用问题. 可直接拿过来用, 由于示例代码看起来比较费劲,特笔记记录:
QT示例参见$(QTDIR)\examples\itemviews\simpletreemodel:
一. 树形结构体定义 treeitem.h
/** * @brief 通用树形结构类 */ class TreeItem { public: TreeItem(const QList<QVariant> &data,TreeItem *parent=0 ); ~TreeItem(); void appendChild(TreeItem *child); TreeItem *child(int row); int childCount() const; int columnCount() const; QVariant data(int column) const; int row() const; TreeItem *parent(); private: TreeItem *parentItem; // 父结点 QList<TreeItem*> childItems; // 子结点列表 QList<QVariant> itemData; // 子节点对应数据 };
二. 树形model实现
#include <QAbstractItemModel> #include "TreeItem.h" class TagTreeModel : public QAbstractItemModel { Q_OBJECT public: TagTreeModel(QObject *parent = 0); ~TagTreeModel(); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; // 构建模型数据 void setupModelData(TreeItem *parent); // 更新模型数据 void updateData(); private: TreeItem *rootItem; // 最顶层顶根节点(一个无效的QModelIndex) };
TagTreeModel.cpp
#include "TagTreeModel.h" #include <QtGui> TagTreeModel::TagTreeModel(QObject *parent):QAbstractItemModel(parent) { rootItem=NULL; updateData(); } TagTreeModel::~TagTreeModel() { delete rootItem; } void TagTreeModel::updateData() { // 废弃旧的模型数据 if(rootItem) { delete rootItem; rootItem=NULL; } QList<QVariant> rootData; rootData<<"Tag"<<"Type"; rootItem=new TreeItem(rootData); setupModelData(rootItem); // 刷新模型 reset(); } QVariant TagTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); // 添加图标 if(role==Qt::DecorationRole&&index.column()==0) return QIcon("images/fold.png"); // 显示节点数据值 if(role==Qt::DisplayRole) { TreeItem *item=static_cast<TreeItem*>(index.internalPointer()); return item->data(index.column()); } return QVariant(); } Qt::ItemFlags TagTreeModel::flags(const QModelIndex &index) const { if(!index.isValid()) return 0; return Qt::ItemIsEnabled|Qt::ItemIsSelectable; } QVariant TagTreeModel::headerData(int section, Qt::Orientation orientation,int role) const { if(orientation==Qt::Horizontal&&role==Qt::DisplayRole) return rootItem->data(section); return QVariant(); } QModelIndex TagTreeModel::index(int row, int column,const QModelIndex &parent) const { if(!hasIndex(row,column,parent)) return QModelIndex(); TreeItem *parentItem; if(!parent.isValid()) { parentItem=rootItem; }else { parentItem=static_cast<TreeItem*>(parent.internalPointer()); } TreeItem *childItem=parentItem->child(row); if(childItem) return createIndex(row,column,childItem); // 展开树形,为子节点建立索引 else return QModelIndex(); } QModelIndex TagTreeModel::parent(const QModelIndex &index) const { if(!index.isValid()) return QModelIndex(); TreeItem *childItem=static_cast<TreeItem*>(index.internalPointer()); TreeItem *parentItem=childItem->parent(); // 顶层节点,直接返回空索引 if(parentItem==rootItem) return QModelIndex(); // 为父结点建立索引 return createIndex(parentItem->row(),0,parentItem); } int TagTreeModel::rowCount(const QModelIndex &parent) const { TreeItem *parentItem; if(!parent.isValid()) parentItem=rootItem; else parentItem=static_cast<TreeItem*>(parent.internalPointer()); return parentItem->childCount(); // 返回父结点下子结点数目 } int TagTreeModel::columnCount(const QModelIndex &parent ) const { return rootItem->columnCount(); } // 设置模型数据,构建包含10个根结点,每个根结点包含两个子节点的树形结构 void TagTreeModel::setupModelData(TreeItem *parent) { for(int i=0;i<10;i++) { QList<QVariant> datas; datas<<QString("设备-%1").arg(i+1)<<QString("类型-%1").arg(i+1); // 主结点下挂两个子节点 TreeItem *primary=new TreeItem(datas,parent); parent->appendChild(primary); for(int j=0;j<2;j++) { QList<QVariant> ds; ds<<QString("子设备-%1").arg(j+1)<<QString("子类型-%1").arg(j+1); primary->appendChild(new TreeItem(ds,primary)); } } }
相关推荐
1. **继承自定义Model**:首先,你需要创建一个类继承自`QAbstractItemModel`。这个类将实现模型所需的所有功能,包括数据的添加、删除、修改和查询,以及索引管理和数据绑定。 2. **数据结构设计**:定义一个内部...
在实际开发中,我们可能需要根据具体需求定制数据模型,这时就需要使用到自定义模型(model)。本教程将深入讲解如何在`QTreeView`中使用自定义模型,以满足特定的数据展示和操作需求。 首先,`QTreeView`依赖于`...
可以使用QTreeView的currentIndex()获取当前选中的索引,然后调用model的removeRow()方法。 ```cpp QModelIndex index = ui->treeView->currentIndex(); if (index.isValid()) { model->removeRow(index.row(), ...
本教程将深入探讨如何实现一个自定义的`QTreeView`,通过重写`QAbstractItemModel`来添加按钮功能,使得每个树节点都可以关联一个可点击的按钮。这在很多实际应用中非常有用,例如在文件管理器、配置界面或者复杂的...
本教程将详细讲解如何自定义QTreeView,添加QPushButton并进行美化。 首先,自绘QTreeView意味着我们需要重写QTreeView的paintEvent()方法,以便可以自定义其显示效果。这涉及到对Qt的图形系统有深入的理解,特别是...
总结起来,自定义代理是Model/View框架中的一个重要工具,它让我们能够灵活地控制数据的呈现,实现独特的视觉效果和交互体验。通过类化代理,我们可以在不改动原有数据模型的情况下,对TreeView中的Item进行自定义...
【标题】"TreeDemo13 自定义model示例"是一个关于使用Qt库创建自定义图形树视图的应用程序。这个示例着重展示了如何利用Qt的模型视图框架(Model/View Framework)来构建一个可拖动节点的树形结构。 在Qt中,模型...
在Qt编程环境中,QTreeview是一个非常重要的控件,它用于显示层次化的数据。当我们处理大量数据时,为QTreeview添加搜索和查找功能是非常有用的,可以提高用户的交互体验。本篇文章将详细介绍如何在QTreeview中实现...
我们将通过分析"qt 自定义tablemodel和使用sqlmodel的例子"中的`TableModelView.zip`和`SqliteExample.zip`两个压缩包文件来阐述相关知识点。 首先,让我们看看自定义`QAbstractTableModel`。`QAbstractTableModel`...
- `custom_model.cpp`:可能包含自定义数据模型的实现,用于展示特定格式的数据。 - `drag_and_drop.cpp`:演示了QTreeView的拖放功能。 - `editing.cpp`:展示了如何启用和处理QTreeView中的编辑操作。 - `sorting....
在`QStandardItemModel`中,可以使用`indexFromItem()`获取目标位置的索引,而在自定义的`QAbstractItemModel`中,可能需要实现自己的逻辑来计算目标索引。 此外,为了提供良好的用户体验,可能还需要自定义拖动...
在提供的代码文件中,如`main.cpp`和`mainwidget.cpp`,你可能已经创建了`QTreeView`实例,并关联了一个`QStandardItemModel`或其他自定义模型。在这些文件中找到合适的位置,按照上述步骤插入展开节点的代码。 ...
model/view 模型将数据与视图分割开来,也就是说,我们可以为不同的视图,QListView、QTableView和QTreeView提供一个数据模型,这样我们可以从不同角度来展示数据的方方面面。但是,面对变化万千的需求,Qt 预定义的...
在本篇详解中,我们将深入探讨QTreeView的工作原理、主要功能以及如何使用它来实现自定义视图。 一、QTreeView的基本结构与工作原理 QTreeView是基于QAbstractItemView的派生类,它与QAbstractItemModel一起工作,...
QTreeView还提供了一些高级特性,例如设置列宽、自定义排序、使用代理模型进行数据过滤和转换等。此外,通过信号和槽机制,可以响应用户对视图的操作,比如点击、展开、折叠等事件,从而实现更复杂的交互逻辑。 在...
在本文中,我们将深入探讨如何使用Qt库中的QTreeView控件来实现数据的增删改操作,并将其保存到数据库中。QTreeView是一个强大的组件,它允许用户以树形结构显示数据,非常适合组织层次化信息。在这个项目中,我们...
在本文中,我们将深入探讨如何在Qt环境中使用`QTreeView`和`QStandardItemModel`来构建和操作一个功能丰富的树形视图。`QTreeView`是Qt中的一个关键组件,它用于显示基于模型的数据结构,而`QStandardItemModel`则是...
但是,如果你需要对特定的子目录进行特殊处理(比如添加图标或自定义行为),可以遍历模型的索引,使用`model->index()`方法获取子目录,并触发视图的更新。 5. **监听信号与槽**:为了响应用户的操作,如打开、...
QTreeView还有许多高级特性,如自定义列宽、排序、选择项、拖放操作以及使用委托进行自定义绘制。你可以通过设置`setHeaderLabels()`来添加列标题,通过`sortByColumn()`进行排序,或者通过重载`QStyledItemDelegate...