问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

MVC软件设计模式及QT的MVC架构

创作时间:
作者:
@小白创作中心

MVC软件设计模式及QT的MVC架构

引用
CSDN
1.
https://m.blog.csdn.net/weixin_62621696/article/details/140820523

MVC(Model-View-Controller)是一种经典的软件设计模式,广泛应用于现代应用程序开发中。本文将深入探讨MVC模式的思想、原理、组成部分,并详细介绍Qt框架中MVC的具体实现方式。通过本文,读者将能够理解MVC模式的核心概念,并掌握如何在Qt中应用MVC架构来开发高质量的用户界面。

引言

在现代软件开发中,MVC(Model-View-Controller)编程模式因其清晰的结构和高效的开发流程而广受青睐。MVC不仅促进了代码的组织和复用,还提高了应用程序的可扩展性和可维护性。本文将深入探讨MVC模式的思想、原理、组成部分、QT中的MVC以及实现简单示例。

一、MVC思想介绍

1.1 MCV模型概述

MVC是一种将应用程序分为三个核心部分的软件设计模式:模型(Model)、视图(View)和控制器(Controller)。这三个部分各自负责不同的职责,通过明确的接口相互通信,共同协作完成应用程序的功能。

  • 模型(Model):负责应用程序的数据和业务逻辑。它代表数据和业务规则,是应用程序的核心。模型接收输入数据,处理业务逻辑,然后返回处理结果。模型与数据库交互,封装了数据的访问逻辑。

  • 视图(View):负责数据的展示和用户界面的渲染。视图从模型接收数据,并将其以用户友好的方式呈现给用户。视图不处理业务逻辑,只是展示数据。

  • 控制器(Controller):作为模型和视图之间的桥梁,处理用户的输入,并调用模型和视图去完成用户的请求。控制器接收用户的输入(如点击按钮、提交表单等),决定使用哪个模型来处理请求,并选择合适的视图来展示结果。

1.2 Excel的处理数据

通过一个简单的例子来理解什么是MVC架构的思想。

以上是一个Excel表格有学生的成绩,在Excel应用中绘制其树状图和折线图。

当修改Excel表格中的数据,树状图和折线图也会随之更改。

简单来说:

模型(Model):就是Excel表格的数据存储;

视图(View):就是树状图和折线图的视图界面;

控制器(Controller):就是处理输入,并更新模型和视图。

1.3 MVC模式的优势

  1. 高内聚低耦合:MVC模式通过将应用程序的不同部分分离,降低了它们之间的耦合度,提高了模块的内聚性,使得修改和扩展变得更加容易。

  2. 易于维护:由于MVC模式将应用程序的不同职责分配给不同的组件,因此当需要修改应用程序时,可以更容易地定位到需要修改的部分,而不会影响到其他部分。

  3. 可重用性:模型和控制器可以被多个视图重用,提高了代码的重用性。

  4. 清晰的分工:MVC模式明确了开发人员之间的分工,提高了开发效率。

二、QT中的MVC

在QT中的 控制器 Controller改了个单词 委托 Delegate,就只是简单改了个单词,性质的一样的。

1.1 模型(Model)

在Qt中,MVC(Model-View-Controller)架构的Model部分负责管理和存储数据,以及提供数据访问的接口。Qt框架提供了一系列的Model类来支持这种架构,这些类通常继承自
QAbstractItemModel
或它的子类。以下是一些关键的Qt Model类及其特点:

  1. QAbstractItemModel
  • 概述:这是所有模型类的基类,定义了模型必须实现的基本接口。由于它是一个抽象类,通常不直接使用,而是使用它的子类。

  • 功能:提供了模型与视图之间进行数据交互的接口,如
    index()
    ,
    parent()
    ,
    rowCount()
    ,
    columnCount()
    等方法。

  1. QStringListModel
  • 概述:这是一个简单的模型类,用于存储和提供QString列表给视图。

  • 特点:适用于需要在视图小部件(如
    QListView

    QComboBox
    )中显示许多字符串的简单情况。

  • 使用场景:当应用程序需要从列表中显示一组字符串时,可以使用
    QStringListModel

  1. QStandardItemModel
  • 概述:这是一个更通用的模型类,提供了用于存储和管理项目数据的标准方式。

  • 特点:支持多维数据(行和列),可以包含不同类型的项(如文本、图标等)。

  • 使用场景:适用于需要表格、列表或树形结构显示数据的复杂情况。

  1. QSqlTableModel 和 QSqlQueryModel
  • 概述:这两个类专门用于与数据库交互,将SQL查询的结果集作为模型数据。

  • 特点

  • QSqlTableModel
    :自动处理多个SQL查询,但通常适用于具有简单表结构的情况。

  • QSqlQueryModel
    :允许执行自定义的SQL查询,并将结果集映射为模型数据。

  • 使用场景:当应用程序需要从数据库中检索数据并在视图中显示时,可以使用这些类。

  1. QAbstractListModel
  • 概述:这是一个一维列表模型的基类,提供了处理一维数据列表的接口。

  • 特点:比
    QStringListModel
    更灵活,可以存储任何类型的数据项。

  • 使用场景:当需要自定义一维列表模型时,可以继承
    QAbstractListModel

  1. QAbstractProxyModel
  • 概述:这是一个代理模型的基类,用于对原始模型的数据进行转换(如排序、过滤等)。

  • 子类:包括
    QSortFilterProxyModel
    (提供排序和过滤功能)和
    QIdentityProxyModel
    (不进行任何修改的代理)。

  • 使用场景:当需要对模型数据进行排序、过滤或其他转换时,可以使用代理模型。

  1. QStyledItemDelegate
  • 概述:虽然
    QStyledItemDelegate
    不是直接的Model类,但它在MVC架构中扮演了重要角色,用于自定义视图中项的显示和编辑。

  • 特点:支持样式表,允许轻松地定制渲染。

  • 使用场景:当需要自定义视图中项的渲染方式时,可以继承
    QStyledItemDelegate

Qt中的MVC Model类提供了丰富的接口和类来支持数据的存储、管理和显示。通过继承和使用这些类,开发者可以轻松地实现复杂的用户界面和数据交互逻辑。在选择Model类时,应根据应用程序的具体需求和数据的特性来决定。

1.2 视图(View)

在Qt中,MVC(Model-View-Controller)架构的View类负责数据的可视化展示,即将模型(Model)中的数据以图形界面的形式呈现给用户。Qt提供了一系列现成的View类,这些类都基于
QAbstractItemView
抽象基类,用于实现不同的数据展示方式。以下是对Qt中MVC的View类的详细介绍:

  1. QAbstractItemView
  • 作用
    QAbstractItemView
    是所有视图类的抽象基类,它定义了视图类所需的基本接口和功能。

  • 特点

  • 提供了视图的基本属性,如选择模式、滚动模式、拖拽支持等。

  • 允许子类通过重写虚函数来自定义视图的行为。

Qt提供了几种具体的View类,以满足不同的数据展示需求:

2. QListView

  • 作用:显示一个项目列表,每个项目占据一行。

  • 特点:支持单选、多选等选择模式,可以通过设置不同的模式来改变用户的选择行为。

3. QTableView

  • 作用:在表格中显示模型中的数据,每个数据项占据一个单元格。

  • 特点:支持行选择、列选择或单元格选择,可以自定义表头、列宽、行高等。

  • 功能:通过
    setAlternatingRowColors
    等函数可以设置表格的交替行颜色,提高可读性。

4. QTreeView

  • 作用:在分层列表中显示模型数据项,通常用于展示具有层级关系的数据。

  • 特点:支持展开/折叠节点,可以根据需要显示或隐藏子项。

  1. 视图类的使用
  • 设置模型:通过调用视图的
    setModel
    函数,将模型与视图关联起来。这样,视图就可以从模型中获取数据并进行展示了。

  • 自定义视图:如果需要自定义视图的展示方式,可以通过继承
    QAbstractItemView
    或现有的视图类,并重写相关函数来实现。

  • 处理用户交互:视图类提供了丰富的信号和槽机制,用于处理用户的交互操作,如选择项的改变、拖拽操作等。

Qt中的MVC架构中的View类提供了丰富的数据展示方式,通过继承
QAbstractItemView
或现有的视图类,并设置模型,可以轻松地实现数据的可视化展示。同时,视图类还提供了丰富的信号和槽机制,用于处理用户的交互操作。

1.3 委托(Delegate)

在Qt的MVC(Model-View-Controller)架构中,虽然Qt官方更偏向于使用Model-View架构(因为Qt没有直接实现一个完整的Controller层,但你可以通过其他方式如信号和槽机制来模拟Controller的行为),Delegate类是一个非常重要的组成部分,它允许你自定义视图(View)中数据的显示和编辑方式。

QStyledItemDelegate类和QItemDelegate类都是Qt框架中用于自定义和控制项视图控件(如QListView、QTableView、QTreeView)中项的显示和编辑的委托类。它们提供了对项的外观和编辑行为的定制能力,但两者之间存在一些关键的区别。

  1. QItemDelegate类
  • 功能:QItemDelegate是Qt中较早期的委托类,用于处理视图中项的显示和编辑。它继承自QAbstractItemDelegate,并提供了默认的绘制和编辑功能。

  • 绘制功能:QItemDelegate使用QStyle进行绘制,这意味着它的绘制风格是基于系统的默认风格。

  • 编辑功能:它提供了默认的编辑器(如文本框、复选框等)和编辑行为。

  • 自定义性:可以通过重写paint和createEditor等虚函数来自定义项的显示和编辑行为。

  • 使用场景:尽管在Qt 4.4之后引入了QStyledItemDelegate,但在一些需要兼容旧版本Qt或特定绘制风格的场景中,QItemDelegate仍然是一个可用的选择。

  1. QStyledItemDelegate类
  • 功能:QStyledItemDelegate是Qt 4.4引入的,旨在替代QItemDelegate,提供更灵活和现代的项委托。它也是继承自QAbstractItemDelegate,并使用QStyle进行绘制。

  • 增强功能

  • 绘制机制:QStyledItemDelegate利用了QStyle的高级功能,可以更好地支持复杂的UI元素和现代风格。

  • 统一的风格:它能更好地与Qt的样式系统集成,确保在不同平台和风格下的外观一致性。

  • 简化的自定义:提供了一些额外的虚函数(如initStyleOption),使自定义项的显示和编辑更加简单和灵活。

  • 使用场景:QStyledItemDelegate是Qt推荐的用于自定义项视图控件中项的显示和编辑的委托类,特别是在需要现代和灵活的绘制风格时。

  1. 比较

特性 QItemDelegate QStyledItemDelegate

引入时间 早期 Qt 4.4

绘制机制 使用QStyle进行绘制,基于系统默认风格 利用QStyle的高级功能,支持更复杂和现代的UI元素

自定义性 可以通过重写paint和createEditor等虚函数来自定义 提供更多虚函数和工具函数,使自定义更加简便和灵活

使用场景 兼容旧版本Qt或特定绘制风格 现代和灵活的绘制风格需求

在选择使用QItemDelegate还是QStyledItemDelegate时,应根据项目需求、Qt版本兼容性以及所需的绘制风格等因素进行综合考虑。在大多数情况下,推荐使用QStyledItemDelegate,因为它提供了更强大和灵活的自定义能力,并且能更好地与Qt的样式系统集成。

  1. 委托类的使用

  2. 创建Delegate类
    继承自
    QStyledItemDelegate
    (或
    QItemDelegate
    ),然后重写
    paint

    createEditor
    (如果需要编辑)以及
    setEditorData

    setModelData
    等函数。

  3. 设置Delegate到View
    使用
    QAbstractItemView
    (如
    QTableView

    QListView
    )的
    setItemDelegate

    setItemDelegateForColumn
    /
    setItemDelegateForRow
    方法来将你的Delegate应用到整个视图或特定的列/行上。

三、简单的实例

在qt设计三个视图控件(ListView、TableView、TreeView)来显示本地系统文件结构,当本地系统文件发生改变,视图也随之改变

UI界面:

代码:


#include "widget.h"  
#include "ui_widget.h"  
#include <QFileSystemModel>  
Widget::Widget(QWidget *parent)  
    : QWidget(parent)  
    , ui(new Ui::Widget)  
{  
    ui->setupUi(this);  
    QFileSystemModel *model = new QFileSystemModel(this);  
    model->setRootPath(QDir::currentPath());  
    ui->listView->setModel(model);  
    ui->listView->setRootIndex(model->index(QDir::currentPath()));  
    ui->treeView->setModel(model);  
    ui->treeView->setRootIndex(model->index(QDir::currentPath()));  
    ui->tableView->setModel(model);  
    ui->tableView->setRootIndex(model->index(QDir::currentPath()));  
}  
Widget::~Widget()  
{  
    delete ui;  
}  

运行结果:

当在系统中添加一个测试文件test.txt视图也随之改变:

四、结论

Qt中的MVC架构通过将应用程序分成模型、视图和控制器三个组件,实现了高内聚、低耦合的设计。这种架构使得Qt应用程序更加模块化、灵活和易于维护。通过合理地使用MVC模式,开发者可以更好地组织和管理Qt应用程序的代码,提高开发效率和应用程序的质量。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号