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.pswp.cn/web/72995.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72995.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72995.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Stream 流中 flatMap 方法詳解

&#x1f3af; 1. flatMap() 到底是啥&#xff1f; flatMap() 是 Stream 里的中間操作&#xff0c;它的作用可以分兩步理解&#xff1a; 第一步&#xff1a;對流里的每個元素&#xff0c;先**映射&#xff08;轉換&#xff09;**成一個 Stream。第二步&#xff1a;把多個子流…

(C語言)理解 回調函數 和 qsort函數

一. 回調函數 1. 什么是回調函數&#xff1f; 回調函數&#xff08;Callback Function&#xff09;是通過 函數指針 調用的函數。其本質是&#xff1a; 將函數作為參數傳遞給另一個函數&#xff0c;并在特定條件下被調用&#xff0c;實現 反向控制。 2. 回調函數的使用 回調函…

vscode記錄

vs code 下載安裝&#xff0c;git 配置&#xff0c;插件安裝_vscode安裝git插件-CSDN博客 手把手教你在VS Code中使用 Git_vscode如何輸入git命令-CSDN博客 VS Code | 如何快速重啟VS Code&#xff1f;_vscode 怎么一鍵全部重啟-CSDN博客 1&#xff0c;安裝插件與git集成 2&am…

唯品會商品詳情頁架構設計與實現:高并發場景下的技術實踐?

引言 唯品會作為國內領先的電商平臺&#xff0c;其商品詳情頁需要應對海量用戶的高并發訪問&#xff0c;同時保證低延遲和高可用性。本文將從架構設計、數據庫優化、緩存策略、前端渲染等方面&#xff0c;結合代碼示例&#xff0c;深入解析唯品會商品詳情頁的技術實現。 一、…

大數據學習(80)-數倉分層

&#x1f34b;&#x1f34b;大數據學習&#x1f34b;&#x1f34b; &#x1f525;系列專欄&#xff1a; &#x1f451;哲學語錄: 用力所能及&#xff0c;改變世界。 &#x1f496;如果覺得博主的文章還不錯的話&#xff0c;請點贊&#x1f44d;收藏??留言&#x1f4dd;支持一…

數智讀書筆記系列021《大數據醫療》:探索醫療行業的智能變革

一、書籍介紹 《大數據醫療》由徐曼、沈江、余海燕合著&#xff0c;由機械工業出版社出版 。徐曼是南開大學商學院副教授&#xff0c;在大數據驅動的智能決策研究領域頗有建樹&#xff0c;尤其在大數據驅動的醫療與健康決策方面有著深入研究&#xff0c;曾獲天津優秀博士論文、…

SpringSecurity——前后端分離登錄認證

SpringSecurity——前后端分離登錄認證的整個過程 前端&#xff1a; 使用Axios向后端發送請求 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登錄</title><script src"https://cdn…

qt下載和安裝教程國內源下載地址

qt不斷在更新中&#xff0c;目前qt6日漸成熟&#xff0c;先前我們到官方下載或者國內鏡像直接可以下載到exe文件安裝&#xff0c;但是最近幾年qt官方似乎在逐漸關閉舊版本下載通道&#xff0c;列為不推薦下載。但是qt5以其廣泛使用和穩定性&#xff0c;以及積累大量代碼使得qt5…

Mysql架構理論部分

Mysql架構是什么&#xff1f;實際可以理解為執行一條sql語句所要經歷的階段有哪些&#xff01; 1.連接層 &#xff08;1&#xff09;客戶端發起連接 客戶端通過TCP/IP、Unix Socket或命名管道等方式向Mysql服務器發起鏈接請求 想要了解tcp與udp的區別&#xff0c;可以參考這…

架構師面試(十九):IM 架構

問題 IM 系統從架構模式上包括 【介紹人模式】和 【代理人模式】。介紹人模式也叫直連模式&#xff0c;消息收發不需要服務端的參與&#xff0c;即客戶端之間直連的方式&#xff1b;代理人模式也叫中轉模式&#xff0c;消息收發需要服務端進行中轉。 下面關于這兩類模式描述的…

【服務器】RAID0、RAID1、RAID5、RAID6、RAID10異同與應用

目錄 ?編輯 一、RAID概述 1.1 磁盤陣列簡介 1.2 功能 二、RAID級別 2.1 RAID 0&#xff08;不含校驗與冗余的條帶存儲&#xff09; 2.2 RAID1&#xff08;不含校驗的鏡像存儲&#xff09; 2.3 RAID 5 &#xff08;數據塊級別的分布式校驗條帶存儲&#xff09; 4、RAI…

MySQL身份驗證的auth_socket插件

在Ubuntu 20.04 LTS上&#xff0c;MySQL 8.0默認使用auth_socket插件進行身份驗證&#xff0c;可能存在意想不到的情況。 一、auth_socket插件 在使用sudo mysql或通過sudo切換用戶后執行任何MySQL命令時&#xff0c;不需要輸入密碼或錯誤密碼都可以正常登入mysql數據庫&…

小程序開發中的用戶反饋收集與分析

我們在開發小程序的過程中根據開發過程中的代碼及業務場景,以下是針對需求管理系統的用戶反饋收集與分析方案設計: 需求管理系統用戶反饋收集與分析方案 一、反饋數據模型設計 // 新增Feedback模型(app/admin/model/Feedback.php) namespace app\admin\model; use think\…

python關鍵字匯總

文章目錄 1. 變量與類型相關2. 控制流相關3. 函數與類相關4. 異常處理相關5. 模塊相關6. 其他 在 Python 3 里有 35 個關鍵字&#xff0c;它們各自具備特定的用途與意義 1. 變量與類型相關 True、False 意義&#xff1a;布爾類型的常量&#xff0c;分別代表邏輯真與邏輯假。示…

使用Python在Word中創建、讀取和刪除列表 - 詳解

目錄 工具與設置 Python在Word中創建列表 使用默認樣式創建有序&#xff08;編號&#xff09;列表 使用默認樣式創建無序&#xff08;項目符號&#xff09;列表 創建多級列表 使用自定義樣式創建列表 Python讀取Word中的列表 Python從Word中刪除列表 在Word中&#xff…

軟考-軟件設計師-計算機網絡

一、七層模型 中繼器&#xff1a;信號會隨著距離的增加而逐漸衰減&#xff0c;中繼器可以接受一端的信息再將其原封不動的發給另一端&#xff0c;起到延長傳輸距離的作用&#xff1b; 集線器&#xff1a;多端口的中繼器&#xff0c;所有端口公用一個沖突域&#xff1b; 網橋&…

關于Flask框架30道面試題及解析

文章目錄 基礎概念1. 什么是Flask?其核心特性是什么?2. Flask和Django的主要區別?3. 解釋Flask中的“路由”概念。如何定義動態路由?核心組件4. Flask的請求上下文(Request Context)和應用上下文(Application Context)有什么區別?5. 如何訪問請求參數?POST和GET方法的…

C++20 中 `constexpr` 的強大擴展:算法、工具與復數庫的變革

文章目錄 一、constexpr 在 <algorithm> 中的應用1. 編譯時排序2. 編譯時查找 二、constexpr 在 <utility> 中的應用1. 編譯時交換2. 編譯時條件交換 三、constexpr 在 <complex> 中的應用1. 編譯時復數運算 四、總結 C20 對 constexpr 的增強是其最引人注目…

【ELK】節省存儲 之 壓縮存儲方式調整

目錄 集群版本&#xff1a; 7.17.6 解釋幾個概念&#xff1a; 段&#xff08;Segment&#xff09; 合并(Merge) 索引設置&#xff1a; 壓縮方式(index.codec)&#xff1a; 測試設置前提條件 對比 在創建的時候指定壓縮類型&#xff08;index.codec&#xff09; 對比 在…

conda create之后,以前的conda env list 只能看到環境路徑 沒有環境名稱了

1.命令 conda env list 看到的顯示如下&#xff1a; 左邊這列的"base"&#xff0c;指向的路徑和其它環境變量安裝的路徑不一致。 這時需要通過"activate [anaconda的環境路徑]"和"source activate"回到anaconda&#xff1a; 2.執行切換命令 …