Qt之MVC架构MVD

什么是MVC架构:

MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

MVC模式最早由Trygve Reenskaug在1978年提出[1],是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式透过对复杂度的简化,使程序结构更加直观。软件系统透过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。专业人员可以依据自身的专长分组:

模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

视图(View) - 界面设计人员进行图形界面设计。

控制器(Controller)- 负责转发请求,对请求进行处理。

Qt的MVD架构又是什么?

模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

视图(View) - 界面设计人员进行图形界面设计。

代理(Delegate)- 负责转发请求,对请求进行处理

UI样式实现:

其实你就只要去实现下面的代码,你就能完全使用MVD架构,随心所欲

class TableModel : public QAbstractTableModel
{Q_OBJECT
public:enum Columns { Element = 0, Value, Count = Value + 1 };explicit TableModel(QObject *parent = nullptr);Qt::ItemFlags flags(const QModelIndex &index) const;int rowCount(const QModelIndex &parent = QModelIndex()) const;int columnCount(const QModelIndex &parent = QModelIndex()) const;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);void addElement(const QString &element, int value);private:};
class TableDelegate : public QStyledItemDelegate
{Q_OBJECT
public:explicit TableDelegate(QObject *parent = nullptr);QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;void setEditorData(QWidget *editor, const QModelIndex &index) const;void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};//--------------------cpp---------------------
#include "tablemodel.h"TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent)
{
}Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{return QAbstractTableModel::flags(index);
}int TableModel::rowCount(const QModelIndex &parent) const
{return 2;
}int TableModel::columnCount(const QModelIndex &parent) const
{return Count;
}QVariant TableModel::data(const QModelIndex &index, int role) const
{return QVariant();
}QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{return QAbstractTableModel::headerData(section, orientation, role);
}bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{if (!index.isValid() || index.row() < 0 || index.row() >= mElements.count()){return false;}return false;
}
void TableModel::addElement(const QString &element, int value)
{
}TableDelegate::TableDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}QWidget *TableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
{return QStyledItemDelegate::createEditor(parent, option, index);
}void TableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QStyledItemDelegate::setEditorData(editor, index);
}void TableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QStyledItemDelegate::setModelData(editor, model, index);
}void TableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QStyledItemDelegate::paint(painter, option, index);
}void TableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,const QModelIndex &index) const
{Q_UNUSED(index)editor->setGeometry(option.rect);
}

Model

class QAbstractItemModel {virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const = 0;virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) = 0;virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0;virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0;virtual Qt::ItemFlags flags(const QModelIndex &index) const = 0;
};

实现上面的代码,你就能使用MVD架构,理解Qt的框架,

View 与 Model 的绑定流程

当调用 view->setModel(model)时:
  1. 存储指针:View 内部保存QAbstractItemModel*类型的指针指向用户的 Model 对象
  2. 信号连接:View 自动连接 Model 的信号(如 dataChanged())到自身的槽(如 update()),实现数据变化时的视图更新
  3. 数据请求:当视图需要渲染时,会通过 Model 指针调用虚函数(如data()rowCount())
// 伪代码:QAbstractItemView 的渲染流程
void QAbstractItemView::paintEvent() {for (int row = 0; row < model->rowCount(); ++row) { // 多态调用 model->rowCount()QVariant data = model->data(index(row));        // 多态调用 model->data()delegate->paint(painter, data);                 // 多态调用 delegate->paint()}
}

Delegate 的动态调用机制

当设置 view->setItemDelegate(delegate)  后:
  1. 渲染阶段:View 在绘制每个数据项时,调用delegate->paint(painter, option, index)
  2. 编辑阶段:当用户双击单元格时,调用delegate->createEditor()创建编辑器
  3. 数据回写:编辑器关闭时,调用delegate->setModelData()将数据写回 Model
// 伪代码:委托的编辑器创建过程
void QAbstractItemView::edit(const QModelIndex &index) {QWidget* editor = delegate->createEditor(parent, option, index); // 多态调用connect(editor, &QWidget::destroyed, [this, index]() {delegate->setModelData(editor, model, index); // 多态调用});
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组,指针 易混题解析(二)

目录 一.基础 1. 2. 二.中等 1. 坑 2. 3.指针1到底加什么 三.偏难 1.&#xff08;小端 x86&#xff09; 2.通过数组指针进行偏移的时候怎么偏移 3. 大BOSS &#xff08;1&#xff09;**cpp &#xff08;2&#xff09;*-- * cpp 3 &#xff08;3&#xff09;*c…

数据建模流程: 概念模型>>逻辑模型>>物理模型

数据建模流程 概念模型 概念模型是一种高层次的数据模型&#xff0c;用于描述系统中的关键业务概念及其之间的关系。它主要关注业务需求和数据需求&#xff0c;而不涉及具体的技术实现细节。概念模型通常用于在项目初期帮助业务人员和技术人员达成共识&#xff0c;确保对业务需…

spring-security原理与应用系列:建造者

目录 1.构建过程 AbstractSecurityBuilder AbstractConfiguredSecurityBuilder WebSecurity 2.建造者类图 SecurityBuilder ​​​​​​​AbstractSecurityBuilder ​​​​​​​AbstractConfiguredSecurityBuilder ​​​​​​​WebSecurity 3.小结 紧接上一篇文…

结合代码理解Spring AOP的概念(切面、切入点、连接点等)

前情回顾 对AOP的理解 我这篇文章介绍了为什么要有AOP&#xff08;AOP解决了什么问题&#xff09;以及如何实现AOP。但在实现AOP的时候&#xff0c;并未探讨AOP相关概念&#xff0c;例如&#xff1a;切面、切入点、连接点等。因此&#xff0c;本篇文章希望结合代码去理解Spring…

【AI大模型】搭建本地大模型GPT-NeoX:详细步骤及常见问题处理

搭建本地大模型GPT-NeoX:详细步骤及常见问题处理 GPT-NeoX是一个开源的大型语言模型框架,由EleutherAI开发,可用于训练和部署类似GPT-3的大型语言模型。本指南将详细介绍如何在本地环境中搭建GPT-NeoX,并解决过程中可能遇到的常见问题。 1. 系统要求 1.1 硬件要求 1.2 软…

Copilot提示词库用法:调整自己想要的,记住常用的,分享该共用的

不论你是 Microsoft 365 Copilot 的新用户还是熟练运用的老鸟&#xff0c;不论你是使用copilot chat&#xff0c;还是在office365中使用copilot&#xff0c;copilot提示词库都将帮助你充分使用copilot这一划时代的产品。它不仅可以帮助你记住日常工作中常用的prompt提示词&…

Spring:AOP

一、AOP概念的引入 为了更好地介绍AOP&#xff0c;我们以登录作为示例。 首先&#xff0c;我们先来看一下登录的原理&#xff1a; 如图所示&#xff0c;这是一个基本的登录原理图&#xff0c;但是如果我们想要在这个登录过程上再添加一些新的功能&#xff0c;比如权限校验&am…

Ubuntu实时读取音乐软件的音频流

文章目录 一. 前言二. 开发环境三. 具体操作四. 实际效果 一. 前言 起因是这样的&#xff0c;我需要在Ubuntu中&#xff0c;实时读取正在播放音乐的音频流&#xff0c;然后对音频进行相关的处理。本来打算使用的PipewireHelvum的方式实现&#xff0c;好处是可以直接利用Helvum…

CUDA 学习(4)——CUDA 编程模型

CPU 和 GPU 由于结构的不同&#xff0c;具有不同的特点&#xff1a; CPU&#xff1a;擅长流程控制和逻辑处理&#xff0c;不规则数据结构&#xff0c;不可预测存储结构&#xff0c;单线程程序&#xff0c;分支密集型算法GPU&#xff1a;擅长数据并行计算&#xff0c;规则数据结…

前端会话控制技术:cookie/session/token

目录 前端中的 Cookie、Session 和 Token&#xff1a;详解与应用1. Cookie1.1 什么是 Cookie&#xff1f;1.2 Cookie 的工作原理1.3 Cookie 的特点1.4 Cookie 的用途1.5 Cookie 的安全性 2. Session2.1 什么是 Session&#xff1f;2.2 Session 的工作原理2.3 Session 的特点2.4…

MATLAB实现基于“蚁群算法”的AMR路径规划

目录 1 问题描述 2 算法理论 3 求解步骤 4 运行结果 5 代码部分 1 问题描述 移动机器人路径规划是机器人学的一个重要研究领域。它要求机器人依据某个或某些优化原则 (如最小能量消耗&#xff0c;最短行走路线&#xff0c;最短行走时间等)&#xff0c;在其工作空间中找到一…

Shopify Checkout UI Extensions

结账界面的UI扩展允许应用开发者构建自定义功能&#xff0c;商家可以在结账流程的定义点安装&#xff0c;包括产品信息、运输、支付、订单摘要和Shop Pay。 Shopify官方在去年2024年使用结账扩展取代了checkout.liquid&#xff0c;并将于2025年8月28日彻底停用checkout.liquid…

电阻的阻值识别

电阻买回来是有偏差的&#xff0c;不同的电阻种类&#xff0c;它的偏差大小会不一样&#xff0c;偏差越小的肯定越贵 主要看要求的精度要求是否越高 色环电阻或者说插件电阻 用来读数的几个色环它是比较靠近的&#xff0c;精度的色环跟用来读数的几个色环的间距会大一点点。 间…

quartz.net条件执行

quartz.net条件执行 在使用Quartz.NET时&#xff0c;你可能需要基于某些条件来决定是否执行一个任务。Quartz.NET本身并不直接支持基于条件执行任务的功能&#xff0c;但你可以通过一些策略来实现这一需求。下面是一些方法来实现基于条件的任务执行&#xff1a; 1. 使用触发器…

计算机操作系统(四) 操作系统的结构与系统调用

计算机操作系统&#xff08;四&#xff09; 操作系统的结构与系统调用 前言一、操作系统的结构1.1 简单结构1.2 模块化结构1.3 分层化结构1.4 微内核结构1.5 外核结构 二、系统调用1.1 系统调用的基本概念1.2 系统调用的类型 总结&#xff08;核心概念速记&#xff09;&#xf…

NSSCTF(MISC)——[SUCTF 2018 招新赛]single-dog

相应的做题地址&#xff1a;https://www.nssctf.cn/problem/2324 分离图片 在1.txt中得到一段颜文字 http://www.hiencode.com/aaencode.html 解密得到flag

低功耗蓝牙(BLE)方案设计实战指南

一、BLE方案设计工具链 1. 硬件选型与开发平台 TI平台&#xff1a;CC2540/CC2541芯片&#xff0c;使用SmartRF Flash Programmer烧录Nordic平台&#xff1a;nRF51822芯片&#xff0c;使用nRFgo Studio管理协议栈常用调试工具&#xff1a;TI CC Debugger、J-Link&#xff08;SW…

网络基础(一)

独立模式与网络互联 独立模式: 计算机之间相互独立。 网络互联&#xff1a;多台计算机连接在一起&#xff0c;完成数据共享。 注意&#xff1a;无论是主机内还是主机外&#xff0c;都是通过线来进行连接的&#xff0c;主机内线&#xff08;线比较短&#xff09;的连接主要考虑…

用Canvas 画布样式实现旋转的阴阳图

用Canvas 画布样式实现旋转的阴阳图 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Canvas八卦图动画</title><style>/* 重置所有元素的默认样式 */* {padding: 0;margin: 0;box-sizin…

第16届蓝桥杯单片机4T模拟赛三

本次模拟赛涉及的模块&#xff1a;基础三件套&#xff08;Led&Relay&#xff0c;按键、数码管&#xff09; 进阶单件套&#xff08;pcf8591的AD模块&#xff09; 附件&#xff1a; 各模块底层代码在文章的结尾 一、数码管部分 1.页面1 页面1要显示的格式是&#xff1a; …