`
tcspecial
  • 浏览: 911452 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

QTreeView 使用自定义Model

    博客分类:
  • QT
阅读更多

        QT对于列表和表格结构都有相应的model实现, 唯独对QTreeView没有提供任何默认实现,只能子类化QAbstractItemModel. 由于树形结构比较复杂,层次结构不固定,用MVC框架实现的确比较费劲. 还好QT提供的这个例子能够处理很多通用问题. 可直接拿过来用, 由于示例代码看起来比较费劲,特笔记记录: 

       QT示例参见$(QTDIR)\examples\itemviews\simpletreemodel:

       Tree Model       

 

一. 树形结构体定义 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));
        }
    }
}

 

 

  • 大小: 28.5 KB
分享到:
评论
2 楼 tcspecial 2016-07-25  
陈宇飞 写道
reset()为什么不可以用了,版本低了,还是头文件呢

本文是在Qt4.8.4上测试的,Qt5的 QAbstractItemModel::reset() 也是存在的。应该与版本关系不大
1 楼 陈宇飞 2016-07-16  
reset()为什么不可以用了,版本低了,还是头文件呢

相关推荐

    QTreeView+自定义Model实现示例

    1. **继承自定义Model**:首先,你需要创建一个类继承自`QAbstractItemModel`。这个类将实现模型所需的所有功能,包括数据的添加、删除、修改和查询,以及索引管理和数据绑定。 2. **数据结构设计**:定义一个内部...

    QTreeView树形视图使用自定义模型model

    在实际开发中,我们可能需要根据具体需求定制数据模型,这时就需要使用到自定义模型(model)。本教程将深入讲解如何在`QTreeView`中使用自定义模型,以满足特定的数据展示和操作需求。 首先,`QTreeView`依赖于`...

    Qt QTreeView使用-QStandardItemModel的使用

    可以使用QTreeView的currentIndex()获取当前选中的索引,然后调用model的removeRow()方法。 ```cpp QModelIndex index = ui-&gt;treeView-&gt;currentIndex(); if (index.isValid()) { model-&gt;removeRow(index.row(), ...

    实现Qtreeview 重写model 实现model中添加按钮的功能

    本教程将深入探讨如何实现一个自定义的`QTreeView`,通过重写`QAbstractItemModel`来添加按钮功能,使得每个树节点都可以关联一个可点击的按钮。这在很多实际应用中非常有用,例如在文件管理器、配置界面或者复杂的...

    自绘QTreeView,添加QPushbutton,并用样式设置按钮,进行美化

    本教程将详细讲解如何自定义QTreeView,添加QPushButton并进行美化。 首先,自绘QTreeView意味着我们需要重写QTreeView的paintEvent()方法,以便可以自定义其显示效果。这涉及到对Qt的图形系统有深入的理解,特别是...

    Model/View框架-自定义代理显示Item

    总结起来,自定义代理是Model/View框架中的一个重要工具,它让我们能够灵活地控制数据的呈现,实现独特的视觉效果和交互体验。通过类化代理,我们可以在不改动原有数据模型的情况下,对TreeView中的Item进行自定义...

    TreeDemo13 自定义model示例.rar

    【标题】"TreeDemo13 自定义model示例"是一个关于使用Qt库创建自定义图形树视图的应用程序。这个示例着重展示了如何利用Qt的模型视图框架(Model/View Framework)来构建一个可拖动节点的树形结构。 在Qt中,模型...

    QTreeview实现搜索功能查找功能

    在Qt编程环境中,QTreeview是一个非常重要的控件,它用于显示层次化的数据。当我们处理大量数据时,为QTreeview添加搜索和查找功能是非常有用的,可以提高用户的交互体验。本篇文章将详细介绍如何在QTreeview中实现...

    qt 自定义tablemodel和使用sqlmodel的例子

    我们将通过分析"qt 自定义tablemodel和使用sqlmodel的例子"中的`TableModelView.zip`和`SqliteExample.zip`两个压缩包文件来阐述相关知识点。 首先,让我们看看自定义`QAbstractTableModel`。`QAbstractTableModel`...

    Qt例程源代码QTreeView.7z

    - `custom_model.cpp`:可能包含自定义数据模型的实现,用于展示特定格式的数据。 - `drag_and_drop.cpp`:演示了QTreeView的拖放功能。 - `editing.cpp`:展示了如何启用和处理QTreeView中的编辑操作。 - `sorting....

    QTreeView拖放

    在`QStandardItemModel`中,可以使用`indexFromItem()`获取目标位置的索引,而在自定义的`QAbstractItemModel`中,可能需要实现自己的逻辑来计算目标索引。 此外,为了提供良好的用户体验,可能还需要自定义拖动...

    QTreeView展开指定位置节点

    在提供的代码文件中,如`main.cpp`和`mainwidget.cpp`,你可能已经创建了`QTreeView`实例,并关联了一个`QStandardItemModel`或其他自定义模型。在这些文件中找到合适的位置,按照上述步骤插入展开节点的代码。 ...

    model?view 自定义模型

    model/view 模型将数据与视图分割开来,也就是说,我们可以为不同的视图,QListView、QTableView和QTreeView提供一个数据模型,这样我们可以从不同角度来展示数据的方方面面。但是,面对变化万千的需求,Qt 预定义的...

    QTreeView详解

    在本篇详解中,我们将深入探讨QTreeView的工作原理、主要功能以及如何使用它来实现自定义视图。 一、QTreeView的基本结构与工作原理 QTreeView是基于QAbstractItemView的派生类,它与QAbstractItemModel一起工作,...

    QTreeView与QStandardItemModel的使用

    QTreeView还提供了一些高级特性,例如设置列宽、自定义排序、使用代理模型进行数据过滤和转换等。此外,通过信号和槽机制,可以响应用户对视图的操作,比如点击、展开、折叠等事件,从而实现更复杂的交互逻辑。 在...

    QTreeView控件实现节点的增删改并保存入库

    在本文中,我们将深入探讨如何使用Qt库中的QTreeView控件来实现数据的增删改操作,并将其保存到数据库中。QTreeView是一个强大的组件,它允许用户以树形结构显示数据,非常适合组织层次化信息。在这个项目中,我们...

    C:\Users\Administrator\Downloads\Qt QTreeView使用-QStandardItemModel的使用

    在本文中,我们将深入探讨如何在Qt环境中使用`QTreeView`和`QStandardItemModel`来构建和操作一个功能丰富的树形视图。`QTreeView`是Qt中的一个关键组件,它用于显示基于模型的数据结构,而`QStandardItemModel`则是...

    仿QFileSystemModel将文件目录在QTreeView中显示

    但是,如果你需要对特定的子目录进行特殊处理(比如添加图标或自定义行为),可以遍历模型的索引,使用`model-&gt;index()`方法获取子目录,并触发视图的更新。 5. **监听信号与槽**:为了响应用户的操作,如打开、...

    Qt QTreeView 简单易学的例子

    QTreeView还有许多高级特性,如自定义列宽、排序、选择项、拖放操作以及使用委托进行自定义绘制。你可以通过设置`setHeaderLabels()`来添加列标题,通过`sortByColumn()`进行排序,或者通过重载`QStyledItemDelegate...

Global site tag (gtag.js) - Google Analytics