Qt 继承QAbstractListModel实现自定义ListModel

1.简介

QAbstractListModel类提供了一个抽象模型,可以将其子类化以创建一维列表模型。

QAbstractListModel为将其数据表示为简单的非层次项目序列的模型提供了一个标准接口。它不直接使用,但必须进行子类化。

由于该模型提供了比QAbstractItemModel更专业的接口,因此不适合与树视图一起使用;如果您想提供一个用于此目的的模型,则需要对QAbstractItemModel进行子类化。如果您需要使用多个列表模型来管理数据,则可能更适合使用子类QAbstractTableModel。

继承QAbstractListModel,需要重写rowCount()、data()、insertRows()、removeRows()等函数。

  • rowCount()函数返回模型的行数。
  • data()函数返回指定索引处的数据。
  • insertRows()插入行
  • removeRows()删除行

2.示例

cpp 复制代码
#ifndef MYLISTMODEL_H
#define MYLISTMODEL_H

#include <QAbstractListModel>
#include <QObject>
#include <QList>

typedef struct _student
{
    QString name;
    int age;
    double score;
}Student;

class MyListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    MyListModel(QObject *parent = nullptr);

    enum RoleNames{
        Name,
        Age,
        Score
    };

public:
    //更新
    void update(QList<Student> students);

    // 返回列表中行的数量
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;

    // 返回指定索引处的数据
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;

    //插入行
    virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());

    //删除行
    virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());

private:
    QList<Student> m_lstStu;
};

#endif // MYLISTMODEL_H


#include "MyListModel.h"

MyListModel::MyListModel(QObject *parent)
    : QAbstractListModel(parent)
{

}

void MyListModel::update(QList<Student> students)
{
    m_lstStu = students;
    for(int i=0;i<m_lstStu.size();i++)
    {
        beginInsertRows(QModelIndex(),i,i);
        endInsertRows();
    }
}

int MyListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_lstStu.size();
}


QVariant MyListModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid())
        return QVariant();

    int nRow = index.row();
    Student stu = m_lstStu.at(nRow);

    if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
        QString ret = QString("%1_%2_%3").arg(stu.name)
                .arg(stu.age).arg(stu.score);

        return ret;
    }

    return QVariant();
}

bool MyListModel::insertRows(int row, int count, const QModelIndex &parent)
{
    if (row >= 0 && row <= m_lstStu.size())
    {
        beginInsertRows(parent, row, row + count - 1);
        for (int i = 0; i < count; ++i)
        {
            //插入一个空的数据
            Student stu;
            stu.name = QString();
            stu.age = 0;
            stu.score = 0;
            m_lstStu.insert(row, stu);
        }
        endInsertRows();
        return true;
    }
    return false;
}


bool MyListModel::removeRows(int row, int count, const QModelIndex &parent)
{
    if (row >= 0 && row + count <= m_lstStu.size())
    {
        beginRemoveRows(parent, row, row + count - 1);
        for (int i = 0; i < count; ++i)
        {
            m_lstStu.removeAt(row);
        }
        endRemoveRows();
        return true;
    }
    return false;
}

使用:

cpp 复制代码
#include "ListForm.h"
#include "ui_ListForm.h"
#include "MyListModel.h"

MyListModel *pModel = nullptr;

ListForm::ListForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ListForm)
{
    ui->setupUi(this);

    //去除选中虚线框
    ui->listView->setFocusPolicy(Qt::NoFocus);

    //设置整行选中
    ui->listView->setSelectionBehavior(QAbstractItemView::SelectRows);

    pModel = new MyListModel(this);

    // 构造数据,更新界面
    QList<Student> students;
    QList<QString> nameList;
    nameList<<"张三"<<"李四"<<"王二"<<"赵五"<<"刘六";

    for (int i = 0; i < 5; ++i)
    {
        Student student;
        student.name = nameList.at(i);
        student.age = qrand()%6 + 13;//随机生成13到19的随机数
        student.score = qrand()%20 + 80;//随机生成0到100的随机数;

        students.append(student);
    }

    pModel->update(students);
    ui->listView->setModel(pModel);
}

ListForm::~ListForm()
{
    delete ui;
}

void ListForm::on_btnInsert_clicked()
{
    if(!pModel)
        return;

    int row = ui->listView->currentIndex().row();

    if(row < 0)
        return;

    pModel->insertRows(row+1,1);
}

void ListForm::on_btnDel_clicked()
{
    if(!pModel)
        return;

    int row = ui->listView->currentIndex().row();

    if(row < 0)
        return;

    pModel->removeRows(row,1);
}
相关推荐
锦亦之22337 小时前
QT+OSG+OSG-earth如何在窗口显示一个地球
开发语言·qt
柳鲲鹏10 小时前
编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
开发语言·qt·mysql
三玖诶10 小时前
如何在 Qt 的 QListWidget 中逐行添加和显示数据
开发语言·qt
阳光开朗_大男孩儿16 小时前
DBUS属性原理
linux·服务器·前端·数据库·qt
Alphapeople17 小时前
Qt Modbus
开发语言·qt
竹林海中敲代码18 小时前
Qt Creator 集成开发环境 常见问题
qt·qt工具常见问题
竹林海中敲代码21 小时前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
长沙红胖子Qt1 天前
关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法
开发语言·qt·qt扩大运行内存
gopher95111 天前
qt相关面试题
开发语言·qt·面试
三玖诶1 天前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式