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);
}
相关推荐
徒步僧11 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
可峰科技12 小时前
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
开发语言·qt
我喜欢就喜欢12 小时前
基于qt vs下的视频播放
开发语言·qt·音视频
CP-DD13 小时前
Qt的架构设计
qt
阿_旭13 小时前
基于YOLO11/v10/v8/v5深度学习的维修工具检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·qt·ai
Bruce小鬼17 小时前
QT创建按钮篇
开发语言·qt
martian66519 小时前
QT开发:掌握现代UI动画技术:深入解析QML和Qt Quick中的动画效果
开发语言·c++·qt·ui
墨染新瑞21 小时前
两个有趣的小东西(qt和类型转换)
开发语言·网络·qt
Bruce小鬼1 天前
解决MAC安装QT启动项目不显示窗口问题
开发语言·qt·macos
云雨歇1 天前
Qt学习笔记(三)网络编程
笔记·qt·学习