QT M/V架构开发实战:M/V架构的初步认识
开发中遇到的问题
- @[TOC](开发中遇到的问题)
- 初步介绍
- 模型类
- 视图类
- 委托
- 实例
开发中遇到的问题
- @[TOC](开发中遇到的问题)
- 初步介绍
- 模型类
- 视图类
- 委托
- 实例
基于版本QT5.14.0
在用了这么久的QT后,在以前做导航栏的控件时,经常使用QPushbutton去做里面的Tab标签(如下图),但是后面用多了之后发现这样的实现方式太麻烦了,而且Tab标签一多就会很卡顿;然后就了解到了QT的MV框架;QT的MV框架其实就是指的是模型-视图框架,模型负责数据,视图负责界面,这样的作法就很好的把数据管理和用户界面展示分离,这样我们进行开发和后期维护都会比较顺利;
初步介绍
在QT中模型和视图都有现成的类供我们去使用,首先是模型的类有:QStandardItemModel
、QStringListModel
、QFileSystemModel
、QSqlQueryModel
、QSqlTableModel
、QSqlRelationalTableModel
等,而这几个都是基于QAbstractItemModel这个抽象基类去实现的;
对应的视图的基类是QAbstractItemView,其子类有QListView
、QTableView
、QTreeView
、QColumnView
等,在这篇文章中我将简单介绍这些模型和视图具体的一个应用场景,每一个类的详细介绍正在推进日程中。。。。
除此以外,其实MV模型还有一个强大的部分,那就是委托,委托可以帮你处理一些项样式,比如你想让这个项变红,那个项变绿,这个项点击变颜色等等操作,这些委托都可以帮你完成!委托的基类为QAbstractItemDelegate,其子类有QStyledItemDelegate
等,常用的就是这个样式委托
模型类
QAbstractItemModel
基类提供最基本的方法,所有子类共用的方法,比如说添加行\列,删除行\列,移动行\列,获取当前的行数\列数等等操作
QStandardItemModel
通用模型,可以存储树形或表格数据(每个单元格是一个 QStandardItem)。非常适合初学者和结构不太复杂的数据。
QStringListModel
专门用于存储简单的字符串列表(如:一列文件名)。类似于QStringList,可以存储所有项的文本
QFileSystemModel
提供本地文件系统的模型(目录和文件)。
QSqlQueryModel || QSqlTableModel || QSqlRelationalTableModel
用于连接和展示数据库数据。使用模型中的方法直接执行Sql语句,将数据拿出来
视图类
QAbstractItemView
一般创建了一个视图对象,就是使用QAbstractItemView中的setModel()方法将视图和模型连接起来
QListView
列表视图,显示一列数据项。参考最开始的图
QTableView
表格视图,显示二维表格数据。参考表格。
QTreeView
树形视图,显示层次结构(树状)数据。参考多级菜单,树形菜单。
QColumnView
列视图(类似 macOS Finder 的列视图)。可以发现QColumnView与QTreeView不同的是,QColumnView可以跨越多列,实际用到的场景的话不是很多。
委托
QStyledItemDelegate
提供单元项的美化和显示操作,如果没有美化效果的话就如QStringListModel中的图片一样,很素,如果加了样式美化的话可以像第一个动图那样好看!除此之外,委托还可以让单元格显示文字,显示控件等等作用
实例
实例一:基本表格
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建视图QTableView tableView;// 创建模型并设置数据QStandardItemModel model(4, 2); // 4行2列model.setHeaderData(0, Qt::Horizontal, "Name");model.setHeaderData(1, Qt::Horizontal, "Age");model.setData(model.index(0, 0), "Alice");model.setData(model.index(0, 1), 25);model.setData(model.index(1, 0), "Bob");model.setData(model.index(1, 1), 31);model.setData(model.index(2, 0), "Carol");model.setData(model.index(2, 1), 29);model.setData(model.index(3, 0), "Dave");model.setData(model.index(3, 1), 40);// 将模型设置给视图tableView.setModel(&model);// 调整列宽以适应内容tableView.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);tableView.resize(400, 300);tableView.show();return app.exec();
}
实例二:自定义委托,大于30的年龄用红色显示
#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include "AgeColorDelegate.h"int main(int argc, char *argv[])
{QApplication app(argc, argv);QTableView tableView;QStandardItemModel model(4, 2);model.setHeaderData(0, Qt::Horizontal, "Name");model.setHeaderData(1, Qt::Horizontal, "Age");model.setData(model.index(0, 0), "Alice");model.setData(model.index(0, 1), 25);model.setData(model.index(1, 0), "Bob");model.setData(model.index(1, 1), 31);model.setData(model.index(2, 0), "Carol");model.setData(model.index(2, 1), 29);model.setData(model.index(3, 0), "Dave");model.setData(model.index(3, 1), 40);tableView.setModel(&model);// 设置委托到第二列(年龄列)AgeColorDelegate *delegate = new AgeColorDelegate(&tableView);tableView.setItemDelegateForColumn(1, delegate);tableView.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);tableView.resize(400, 300);tableView.show();return app.exec();
}
实例三:下拉框委托
#ifndef COMBOBOXDELEGATE_H
#define COMBOBOXDELEGATE_H#include <QStyledItemDelegate>class ComboBoxDelegate : public QStyledItemDelegate
{Q_OBJECT
public:explicit ComboBoxDelegate(QObject *parent = nullptr);QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const override;void setEditorData(QWidget *editor, const QModelIndex &index) const override;void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const override;void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const override;
};#endif // COMBOBOXDELEGATE_H
自己动手看一下效果,冲冲冲!!!!!
以上的话就是本文的全部内容,如果有什么错误或者建议请指正,感谢!共同进步!