QT M/V架构开发实战:M/V架构的初步认识

### 开发中遇到的问题

  • [@[TOC](开发中遇到的问题)](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)
  • [初步介绍](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)
  • [模型类](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)
  • [视图类](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)
  • [委托](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)
  • [实例](#开发中遇到的问题 @TOC 初步介绍 模型类 视图类 委托 实例)

基于版本QT5.14.0

在用了这么久的QT后,在以前做导航栏的控件时,经常使用QPushbutton去做里面的Tab标签(如下图),但是后面用多了之后发现这样的实现方式太麻烦了,而且Tab标签一多就会很卡顿;然后就了解到了QT的MV框架;QT的MV框架其实就是指的是模型-视图框架,模型负责数据,视图负责界面,这样的作法就很好的把数据管理和用户界面展示分离,这样我们进行开发和后期维护都会比较顺利;

初步介绍

在QT中模型和视图都有现成的类供我们去使用,首先是模型的类有:QStandardItemModelQStringListModelQFileSystemModelQSqlQueryModelQSqlTableModelQSqlRelationalTableModel等,而这几个都是基于QAbstractItemModel这个抽象基类去实现的;

对应的视图的基类是QAbstractItemView ,其子类有QListViewQTableViewQTreeViewQColumnView等,在这篇文章中我将简单介绍这些模型和视图具体的一个应用场景,每一个类的详细介绍正在推进日程中。。。。

除此以外,其实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中的图片一样,很素,如果加了样式美化的话可以像第一个动图那样好看!除此之外,委托还可以让单元格显示文字,显示控件等等作用

实例

实例一:基本表格

cpp 复制代码
#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的年龄用红色显示

cpp 复制代码
#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();
}

实例三:下拉框委托

cpp 复制代码
#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

自己动手看一下效果,冲冲冲!!!!!

以上的话就是本文的全部内容,如果有什么错误或者建议请指正,感谢!共同进步!

相关推荐
长路归期无望2 小时前
C语言小白实现多功能计算器的艰难历程
c语言·开发语言·数据结构·笔记·学习·算法
恒悦sunsite2 小时前
Ubuntu之apt安装ClickHouse数据库
数据库·clickhouse·ubuntu·列式存储·8123
是大强2 小时前
stm32摇杆adc数据分析
开发语言
奥尔特星云大使2 小时前
MySQL 慢查询日志slow query log
android·数据库·mysql·adb·慢日志·slow query log
来自宇宙的曹先生2 小时前
MySQL 存储引擎 API
数据库·mysql
间彧3 小时前
MySQL Performance Schema详解与实战应用
数据库
间彧3 小时前
MySQL Exporter采集的关键指标有哪些,如何解读这些指标?
数据库
weixin_446260853 小时前
Django - 让开发变得简单高效的Web框架
前端·数据库·django
蓝莓味的口香糖3 小时前
【JS】什么是单例模式
开发语言·javascript·单例模式
mpHH3 小时前
babelfish for postgresql 分析--todo
数据库·postgresql