作者:神秘的sy0001 | 来源:互联网 | 2023-09-01 17:20
下面来尝试实现qabstractlistmodel的子类化。
首先新建c++类,继承在qabstractlistmodel类的stringlistmodel:
思路如下:
首先实现子类化的类,在类里实现列表的基本功能,再在widget构造函数里实现具体的控件功能,从而考察这个思路是否正确。只要改变string的值,是不是视图就自动跟着改变。
下面时子类化以后的编译通过界面:
这里放置了两个控件,一个是listview,一个是tableview,因为这里没有考虑层级关系,所以就不用treeview,只考虑这两个就可以。
先来实现一个头声明
#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H#include
#include class StringListModel : public QAbstractListModel
{Q_OBJECT
public:
// explicit StringListModel(QObject *parent = 0);StringListModel(const QStringList &strings, QObject *parent = 0):QAbstractListModel(parent),stringList(strings){}int rowCount(const QModelIndex &parent = QModelIndex()) const;QVariant data(const QModelIndex &index, int role) const;QVariant headerData(int Section, Qt::Orientation orientation,int role = Qt::DisplayRole) const;
signals:public slots:private:QStringList stringList;
};#endif // STRINGLISTMODEL_H
再来实现具体的cpp函数
#include "stringlistmodel.h"//StringListModel::StringListModel(QObject *parent) :
// QAbstractListModel(parent)
//{
//}int StringListModel::rowCount(const QModelIndex &parent) const
{return stringList.count();
}QVariant StringListModel::data(const QModelIndex &index, int role) const
{if(!index.isValid())return QVariant();if(index.row()>=stringList.size())return QVariant();if(role==Qt::DisplayRole)return stringList.at(index.row());elsereturn QVariant();
}QVariant StringListModel::headerData(int Section, Qt::Orientation orientation,int role) const
{if(role!=Qt::DisplayRole)return QVariant();if(orientation==Qt::Horizontal)return QString("Column %1").arg(Section);elsereturn QString("Row %1").arg(Section);
}
到这一步都是编译通过的,没问题。
下面开始在widget中实现:
#include "widget.h"
#include "ui_widget.h"#include "stringlistmodel.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);QStringList list;list<<"第1个项目: 孙悟空"<<"第2个项目: 沙师弟"<<"第3个项目: 刘畊宏";StringListModel *model &#61; new StringListModel(list);ui->listView->setModel(model);}Widget::~Widget()
{delete ui;
}
这里只实现了和listview的绑定&#xff1a;
正常显示。
接着绑定了tableview 也正常&#xff0c;还能显示header信息。
这里不太好理解的是&#xff0c;创建stringlist对象后&#xff0c;他的成员函数好像都没调用&#xff0c;但如果没有的话&#xff0c;估计view是无法正常显示的。试一试。比如把headerdata函数去掉&#xff0c;那么就是&#xff1a;
果不其然&#xff0c;在setmodel的时候&#xff0c;其实这些函数是在生效的。只是不在明面上而已。
如果把rowcount函数略去&#xff0c;则会报错&#xff01;
、
所以在子类化的时候&#xff0c;这几个问题还是要注意的。
如果直接使用qabstractitemmodel&#xff0c;也可以实现setmodel&#xff0c;只是数据得一个一个敲上去。
下面试一下如果我改变字符串&#xff0c;是不是能实时更新&#xff1f;
实践证明&#xff0c;list改变后&#xff0c;必须重新setmodel才能更新。