设为首页 加入收藏

TOP

【Qt6】列表模型——便捷类型(一)
2023-09-23 15:43:59 】 浏览:372
Tags:Qt6

前一篇水文中,老周演示了 QAbstractItemModel 抽象类的继承方法。其实,在 Qt 的库里面,QAbstractItemModel 类也派生了两个基类,能让开发者继承起来【稍稍】轻松一些。

这两个类是 QAbstractListModel 和 QAbstractTableModel。

  • QAbstractListModel类专门用来实现一维列表结构模型的。它实现了 index、parent 等方法,并且把 columnCount 方法变成了私有成员(一维列表不需要它)。继承时直接实现 rowCount、data、setData 这几个方法即可;
  • QAbstractTableModel类专门用来实现二维表结构的模型。它实现了 index、parent 等方法。继承时咱们要实现 rowCount、columnCount、data、setData 等方法。

虽然它帮咱们实现了一些成员,但实际上也省不了多功夫的。下面咱们用 QAbstractListModel 举例,和上篇中的一样,操作一个 QList<int> 数据。毕竟一维的比较简单,演示出来大伙都容易懂。

// 头文件
#ifndef LIST_H
#define LIST_H

#include <QAbstractListModel>
#include <QList>

class CustListModel: public QAbstractListModel
{
    Q_OBJECT

public:
    explicit CustListModel(QObject* parent = nullptr);
    ~CustListModel();

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);

    bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;

    Qt::ItemFlags flags(const QModelIndex &index) const override;
private:
    // 私有,存数据用
    QList<int> m_list;
};

#endif

先弄 rowCount 方法,返回总行数,这个简单一点。

int CustListModel::rowCount(const QModelIndex &parent) const
{
    if(parent.isValid())
    {
        return 0;
    }
    return m_list.size();
}

实现 data 方法,获取数据时用。

QVariant CustListModel::data(const QModelIndex &index, int role) const
{
    if( role == Qt::DisplayRole || role == Qt::EditRole)
    {
        if(!index.isValid())
        {
            return QVariant();
        }
        // 获取索引
        int i = index.row();
        // 返回指定索引处的值
        return m_list.at(i);
    }
    return QVariant();
}

要返回 QList<T> 中指定的元素,用 at 方法,传递索引给它即可。

实现 setData 方法,编辑结束后用于更新数据的。

bool CustListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    if(role == Qt::EditRole || role == Qt::DisplayRole)
    {
        // 解包数据
        bool ok;
        int val = value.toInt(&ok);
        if(ok)
        {
            // 设置值
 m_list.replace(index.row(), val);

              // 发出信号
              emit dataChanged(index,index,{role});

return true;
        }
    }
    return false;
}

要修改某个索引处的值,用 replace 方法替换。

实现 flags 方法,表明该模型的列表项支持交互、编辑、被选择。

Qt::ItemFlags CustListModel::flags(const QModelIndex &index) const
{
    return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
}

ItemIsEnabled 表明列表项是活动的,用户可操作的;ItemIsEditable 表明列表项可编辑;ItemIsSelectable 表示列表项可以选择。

 

下面这两个方法是有点麻烦的,这里先介绍一下。

bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());

row 参数表示要插入元素的索引,count 表示插入元素个数,插入元素后,原来的元素向后移动。例如:A、B、C、D,现在我要在B处插入两个元素。那么 row = 1,count = 2,B 处放入 E、F,B、C、D 向后移,变成 A、E、F、B、C、D。

然后,删除元素的方法也类似。

bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());

row 是要删除的索引,count 是连续要删掉的元素个数。

insertRows 和 removeRows 方法的返回值含义相同:成功返回 true,失败返回 false。

好,现在上代码。

bool CustListModel::insertRows(int row, int count, const QModelIndex &parent)
{
    if(parent.isValid())
        return false;
    // 注意这里!!
    beginInsertRows(parent, row, row + count - 1);
    // 开始插入
    m_list
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++ 学习笔记、01 | 开发简单职工.. 下一篇5.0 CRC32校验技术概述

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目