Qt inherits QAbstractListModel to implement a custom ListModel

1. Introduction

QAbstractListModel is an abstract class in the Qt framework, used to implement the data model and used to display and edit list data in Qt’s view components. Similar to QAbstractTableModel, it is also an abstract class that provides some basic interfaces and default implementations to easily create customized list data models.

The main functions of QAbstractListModel include the following:

  • Obtaining and setting data: By implementing the data() and setData() interfaces, it can be used to obtain and set data in the list. You can perform related operations in these two interfaces according to your own data structure and logic. The data() method is used to obtain the data at the specified index position, and the setData() method is used to set the data at the specified index position.
  • Management of list items: You can get the number of items in the list through the rowCount() method. You can also dynamically add or remove list items through the insertRows() and removeRows() methods.
  • List display and editing: You can determine how list data is displayed and edited in the view by implementing displayRole and editRole related methods. You can also specify the editing properties of each list item by implementing the flags() method.
  • Sorting of data: You can sort the data in the list by implementing the sort() method.

Because this model provides a more specialized interface than QAbstractItemModel, it is not suitable for use with tree views; if you want to provide a model for this purpose, you will need to subclass QAbstractItemModel. If you need to use multiple list models to manage data, subclassing QAbstractTableModel may be more appropriate.

Inheriting QAbstractListModel requires rewriting rowCount(), data(), insertRows(), removeRows() and other functions.

  • The rowCount() function returns the number of rows in the model.
  • The data() function returns the data at the specified index.
  • insertRows() insert rows
  • removeRows() deletes rows

2.Example

Declare the data structure:

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

Rewrite functions such as rowCount(), data(), insertRows(), and removeRows().

#ifndef MYLISTMODEL_H
#defineMYLISTMODEL_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:
    //renew
    void update(QList<Student> students);

    // Return the number of rows in the list
    virtual int rowCount(const QModelIndex & amp;parent = QModelIndex()) const;

    // Return the data at the specified index
    virtual QVariant data(const QModelIndex & amp;index, int role = Qt::DisplayRole) const;

    //Insert row
    virtual bool insertRows(int row, int count, const QModelIndex & amp;parent = QModelIndex());

    //delete row
    virtual bool removeRows(int row, int count, const QModelIndex & amp;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 & amp;parent) const
{
    Q_UNUSED(parent);
    return m_lstStu.size();
}


QVariant MyListModel::data(const QModelIndex & amp;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 & amp;parent)
{
    if (row >= 0 & amp; & amp; row <= m_lstStu.size())
    {
        beginInsertRows(parent, row, row + count - 1);
        for (int i = 0; i < count; + + i)
        {
            //Insert an empty data
            Student study;
            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 & amp;parent)
{
    if (row >= 0 & amp; & amp; 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;
}

Usage example:

#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);

    //Remove selected dotted box
    ui->listView->setFocusPolicy(Qt::NoFocus);

    //Set the entire row to be selected
    ui->listView->setSelectionBehavior(QAbstractItemView::SelectRows);

    pModel = new MyListModel(this);

    // Construct data and update the interface
    QList<Student> students;
    QList<QString> nameList;
    nameList<<"Zhang San"<<"Li Si"<<"Wang Er"<<"Zhao Wu"<<"Liu Liu";

    for (int i = 0; i < 5; + + i)
    {
        Student student;
        student.name = nameList.at(i);
        student.age = qrand()%6 + 13;//Randomly generate random numbers from 13 to 19
        student.score = qrand() + 80; // Randomly generate a random number from 0 to 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);
}

3. Recommendation

Qt inherits QAbstractTableModel to implement a custom TableModel-CSDN Blog

Detailed explanation of Qt plug-in development_qt plug-in development-CSDN blog

Qt inherits QAbstractTableModel to implement a custom TableModel-CSDN Blog