文章目录
1、自定义模型的介绍
在Qt中,MVC(Model-View-Controller)模式是常用的模式之一,用于将应用程序中的数据(Model)与用户界面(View)分离开来。自定义模型允许开发者使用自己的数据结构作为模型,并将其与Qt的视图部件结合使用。
自定义模型需要实现Qt中的抽象模型类(QAbstractItemModel)中的纯虚函数。其中,最基本的函数包括rowCount()、columnCount()、data()和index()函数。rowCount()和columnCount()函数返回模型中行和列的数量,data()函数用于获取模型中某个单元格的数据,而index()函数返回模型中指定行和列的QModelIndex对象。
开发者还可以实现其他函数,如headerData()函数用于返回模型的列标题和行标题,以及setData()函数用于设置模型中某个单元格的数据。在自定义模型中还可以使用信号和槽机制,以便在数据发生变化时通知视图部件进行更新。
自定义模型可以与Qt的各种视图部件一起使用,如QTableView、QListView、QTreeView等。开发者需要将自定义模型设置为视图部件的模型,并在必要时重写视图部件中的一些函数,以确保正确地使用自定义模型。
2、自定义模型的实现
如下我将通过自定义一个字符串列表模型,让它继承于QAbstractListModel,
实现自定义的列表模型,然后通过视图显示出来。
StringListModel.h如下:
#pragma once
#include <QAbstractListModel>
#include<QStringList>
class StringListModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit StringListModel(QStringList list, QObject* parent = nullptr);
~StringListModel();
protected:
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
virtual QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
private:
QStringList strList;
};
StringListModel.cpp如下:
#include "StringListModel.h"
StringListModel::StringListModel(QStringList list, QObject* parent) :
QAbstractListModel(parent),strList(list)
{
}
StringListModel::~StringListModel()
{}
int StringListModel::rowCount(const QModelIndex & parent) const
{
return strList.count();
}
QVariant StringListModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (index.row() >= strList.size())
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
return strList.at(index.row());
}
else
{
return QVariant();
}
}
bool StringListModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (index.isValid() && role == Qt::EditRole)
{
strList.replace(index.row(), value.toString());
//通知view调用model中的data渲染界面
emit dataChanged(index, index);
return true;
}
return false;
}
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);
}
else if (orientation == Qt::Vertical)
{
return QString("Row %1").arg(section);
}
}
Qt::ItemFlags StringListModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
{
return Qt::ItemIsEnabled;
}
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
main.cpp如下:
#include "MainWindow.h"
#include <QtWidgets/QApplication>
#include<QListView>
#include<QStringList>
#include<QTableView>
#include"StringListModel.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//将数据存入model中
QStringList list;
list << "naruto" << "healer" << "sakura";
StringListModel model(list);
QListView listView;
listView.setModel(&model);
listView.show();
QTableView tableView;
tableView.setModel(&model);
tableView.show();
#if 0
MainWindow w;
w.show();
#endif
return a.exec();
}
代码点的测试结果如下:
总结:我们为自定义的StringList模型添加的两个函数flags()和setData()函数。
flags函数用来判断模型索引对应的项目的属性,通过标记按位或的方式获取。
setData用来设置模型索引对应的项,并且设置他的编辑属性。
headerData()函数实现显示列表的表头。