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)); } } }
相关推荐
QTreeView是用来显示树型结构的数据,比如目录组织,公司组织架构等,数据量小可以用Qt自带的Model实现,如果数据量大,则需要用自定义的Model实现,下面介绍自定义实现的方法。
QTreeView树形视图使用自定义模型model,不是改造QT例子。
详细介绍QTreeView的使用, 包括:模型/视图,自定义委托、自定义样式等操作 以及无边框界面的拖拽等操作!
自定义的QTreeView+Model实现树节点内部之间拖拽效果,同时实现通过点击按钮的方式向QTreeView中添加节点。
具体介绍见: Qt树形控件QTreeView使用1——节点的添加删除操作: http://blog.csdn.net/czyt1988/article/details/18996407 Qt树形控件QTreeView使用2——复选框的设置: ...利用C++11的function和bind功能,实现...
通过qtreeview 重写treemodel 实现树节点不同的特性,然后操作item的delegate绘制控件。
QTreeView Checkboxes 需要实现一个功能:在QT的TreeView中,能够使用复选框,并且选中父节点的复选框可以全选或取消子节点的复选框。 参考链接: http://blog.csdn.net/ajaxhe/article/details/7518285