Qt MVC之自定义Model

文章介绍了如何在Qt中实现自定义模型,特别是通过继承QAbstractListModel创建一个字符串列表模型。这个模型支持数据的显示、编辑和头部信息,可用于QListView和QTableView等视图组件。关键函数包括rowCount、columnCount、data、index、setData和headerData,以及信号和槽机制来处理数据变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()函数实现显示列表的表头。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值