关于TreeView的简单使用(Qt6.4.1)

前言

TreeView是在Qt6.3中加入的,弥补了Qt中无官方树图。笔者上手尝试了下,虽然有点麻烦,但官方也做了不少简化。

本次教程,笔者创建一个简单的示例,以帮助读者使用TreeView。

一、创建模型类

当前模型需要使用C++定义,模型类继承自QAbstractItemModel,笔者的头文件如下

class TreeItem;

class TreeModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    enum TreeRole {
        FullNameRole = Qt::DisplayRole,
        AddressRole = Qt::UserRole
    };
    Q_ENUM(TreeRole)
    explicit TreeModel(QObject *parent = nullptr);
    ~TreeModel();

    // Header:
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

//    bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;

    // Basic functionality:
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

    // Editable:
    bool setData(const QModelIndex &index, const QVariant &value,
                 int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex& index) const override;


private:

    void setupModelData(TreeItem *parent);
    TreeItem *getItem(const QModelIndex &index) const;

    TreeItem *rootItem;
};

与TableView的模型相关,多了index()和parent()的实现

模型类实现后,可以注册到qml中

qmlRegisterType<TreeModel>("TreeModelTest", 1, 0, "TreeModel");

二、显示模型数据

TreeView {
    id: treeView
    //模型
    model: TreeModel {}
    //委托
    delegate: TreeViewDelegate {}
    //边界操作
    boundsBehavior: Flickable.StopAtBounds
    //水平滚动条
    ScrollBar.horizontal: ScrollBar {}
    //垂直滚动条
    ScrollBar.vertical: ScrollBar {}
}

 树形视图的实现比较好理解,可以调整很多属性

TreeViewDelegate是Qt内置的委托,也可以自定义实现

注:

TreeView继承自TableView,所以TableView可以使用的东西,TreeView也可以使用。

三、添加水平表头

HorizontalHeaderView {
        id: tableView_topHeader
        anchors.left: treeView.left
        anchors.right: treeView.right
        anchors.top: parent.top
        syncView: treeView
    }

 若不指定水平表头的模型数据,默认会调用模型的headerData()函数获取,需要在C++中实现。

syncView属性可以将treeView的水平位置或列宽等信息,同步到水平表头,这样就不要再单独调用相关属性了。

注:

HorizontalHeaderView继承自TableView,所以TableView可以使用的东西,HorizontalHeaderView也可以使用。

四、添加垂直表头

VerticalHeaderView {
        id: tableView_leftHeader
        anchors.left: parent.left
        anchors.top: treeView.top
        anchors.bottom: treeView.bottom
        syncView: treeView
        model: treeView.rows
    }

若不指定水平表头的模型数据,默认会调用模型的headerData()函数获取,但要注意,headerData()只能返回最顶层的表头数据,导致显示异常。笔者建议直接绑定TreeView的行数或自定义。

syncView属性可以将treeView的垂直位置或列高等信息,同步到垂直表头,这样就不要再单独调用相关属性了。

注:

VerticalHeaderView继承自TableView,所以TableView可以使用的东西,VerticalHeaderView也可以使用。

五、增加选择功能

TreeView {
    id: treeView
    //模型
    model: TreeModel {}
    //选择模型
    selectionModel:  ItemSelectionModel{ id: itemSelectionModel}
    //委托
    delegate: TreeViewDelegate {}
    //边界操作
    boundsBehavior: Flickable.StopAtBounds
    //水平滚动条
    ScrollBar.horizontal: ScrollBar {}
    //垂直滚动条
    ScrollBar.vertical: ScrollBar {}
}

笔者测试了下Qt自带的选择模型,win10下效果还不错,但在android下的效果欠佳

  

六、读取模型数据

treeView.delegate: TreeViewDelegate {
        TapHandler {
            acceptedButtons: Qt.RightButton
            onTapped: {
                console.debug("currentIndex",row,column,index,
                              treeView.modelIndex(column, row),
                              model.display )
            }
        }

    }

 TreeView读取模型数据,和一般视图相同,但也有一些区别。和其他视图-模型不同,TreeView的row、column是视图中的显示的行与列(从0开始),index是视图中的列向叠加序列(自上而下,先计算第0列,再依次叠加后面几列)。模型中的行是相对于父对象的。也就是说,视图的row、column、index与模型中的不同,但存在对应关系。可以TreeView里的函数获取,如 columnAtIndex()、 modelIndex()、 rowAtIndex()等。

笔者使用的测试源码

后记

TreeView可以自定义表头,以实现复杂的表头设计。

时间所限,笔者只是显示了TreeView的简单用法,且仅在win10和android下简单测试。其中定有不足,请小伙伴指正。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁白杨树下꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值