日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

Qt中的模型视图设计模式

發布時間:2025/4/5 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt中的模型视图设计模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 初探Qt中的模型視圖設計模式
    • 2 模型視圖中的索引
    • 3 模型中的數據組織方式初探

1 初探Qt中的模型視圖設計模式

模型視圖設計模式的核心思想:

  • 模型(數據)與視圖(顯示)相分離。
  • 模型對外提供標準接口存取數據(不關心數據如何顯示)。
  • 視圖自定義數據的顯示方式(不關心數據如何組織存儲)。

模型視圖模式的直觀理解:

模型視圖模式的工作機制:

  • 當數據發生改變時:模型發出信號通知視圖。
  • 當用戶與視圖進行交互時:視圖發出信號提供交互信息。

Qt中的模型類層次結構:

Qt中視圖類的層次結構:

關鍵技術問題:模型如何為數據提供統一的訪問方式?

深入理解:在Qt中,不管模型以什么結構組織數據,都必須為每一個數據提供獨一無二的索引;視圖通過索引訪問模型中的具體數據。

模型視圖編程示例:

Widget.h:

#ifndef WIDGET_H #define WIDGET_H#include <QtGui/QWidget> #include <QFileSystemModel> #include <QTreeView>class Widget : public QWidget {Q_OBJECTQFileSystemModel m_fsModel;QTreeView m_treeView; public:Widget(QWidget *parent = 0);~Widget(); };#endif // WIDGET_H

Widget.cpp:

#include "Widget.h" #include <QDir>Widget::Widget(QWidget *parent): QWidget(parent) {m_treeView.setParent(this);m_treeView.move(10, 10);m_treeView.resize(500, 300);m_fsModel.setRootPath(QDir::currentPath());m_treeView.setModel(&m_fsModel);m_treeView.setRootIndex(m_fsModel.index(QDir::currentPath())); }Widget::~Widget() {}

main.cpp:

#include <QtGui/QApplication> #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }

對模型視圖設計模式總結一下:

  • 模型定義標準接口(成員函數)對數據進行訪問。
  • 視圖通過標準接口獲取數據并定義顯示方式。
  • 模型使用信號與槽的機制通知視圖數據變化。
  • 模型的數據都是以層次結構表示的。

2 模型視圖中的索引

模型中的索引:

  • 模型索引是數據與視圖分離的重要機制。
  • 模型中的數據使用唯一的索引來訪問。
  • 索引是訪問模型中具體數據的約定方式。
  • QModelIndex是Qt中的模型索引類:
    • 包含具體數據的訪問途徑。
    • 包含一個指向模型的指針。

索引的意義:

索引中的行和列:

  • 線性模型可以使用(row,column)作為數據索引。

    問題:只用行和列描述數據索引是否足夠通用?

思考:

  • 如何索引以屬性結構組織的數據?

模型中的通用樹形結構:
模型中數據索引的通用方式:

  • 三元組:(row、column、parent)。
  • 索引在需要時由模型實時創建。
  • 使用空索引作為父節點表示頂層數據元素。
  • 特殊的模型可以自定義特殊的索引獲取方式。


    編程實驗:數據索引深入理解

Widget.h:

#ifndef WIDGET_H #define WIDGET_H#include <QtGui/QWidget> #include <QPlainTextEdit> #include <QFileSystemModel>class Widget : public QWidget {Q_OBJECTQPlainTextEdit m_edit;QFileSystemModel m_fsm; protected slots:void onDirectoryLoaded(const QString& path); public:Widget(QWidget *parent = 0);~Widget(); };#endif // WIDGET_H

Widget.cpp:

#include "Widget.h" #include <QDir> #include <QModelIndex> #include <QByteArray> #include <QBuffer> #include <QTextStream>Widget::Widget(QWidget *parent): QWidget(parent) {m_edit.setParent(this);m_edit.move(10, 10);m_edit.resize(500, 300);connect(&m_fsm, SIGNAL(directoryLoaded(QString)), this, SLOT(onDirectoryLoaded(QString)));m_fsm.setRootPath(QDir::currentPath()); }void Widget::onDirectoryLoaded(const QString& path) {QModelIndex root = m_fsm.index(path);QByteArray array;QBuffer buffer(&array);if( buffer.open(QIODevice::WriteOnly) ){QTextStream out(&buffer);out << m_fsm.isDir(root) << endl;out << m_fsm.data(root).toString() << endl;out << root.data().toString() << endl;out << &m_fsm << endl;out << root.model() << endl;out << m_fsm.filePath(root) << endl;out << m_fsm.fileName(root) << endl;out << endl;for(int i=0; i<m_fsm.rowCount(root); i++){QModelIndex ci = m_fsm.index(i, 0, root);out << ci.data().toString() << endl;}out.flush();buffer.close();}if( buffer.open(QIODevice::ReadOnly) ){QTextStream in(&buffer);m_edit.insertPlainText(in.readAll());buffer.close();} }Widget::~Widget() {}

main.cpp:

#include <QtGui/QApplication> #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }

后面需要解決一個問題:QFileSystemModel中是如何組織數據的?如何手動解析QFileSystemModel中的數據?


3 模型中的數據組織方式初探

問題:不同的視圖如何顯示同一個模型中的數據?

Qt中的標準模型定義:

MainWindow.h:

#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QtGui/QMainWindow> #include <QTableView> #include <QStandardItemModel> class MainWindow : public QMainWindow {Q_OBJECT private:QStandardItemModel m_standerdModel;QTableView m_tableView;void initStanderdModel();void initTableModel(); public:MainWindow(QWidget *parent = 0);~MainWindow(); };#endif // MAINWINDOW_H

MainWindow.cpp:

#include "MainWindow.h" #include <QStandardItem>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {initStanderdModel();initTableModel();m_tableView.setModel(&m_standerdModel); } void MainWindow::initStanderdModel() {QStandardItem* root = m_standerdModel.invisibleRootItem();QStandardItem* itemA = new QStandardItem();QStandardItem* itemB = new QStandardItem();QStandardItem* itemC = new QStandardItem();itemA->setData("A");//只是往數據項里面放了數據,并沒有告訴如何顯示itemA->setData("Tip A");itemA->setData("Help A");itemB->setData("B");itemB->setData("Tip B");itemC->setData("C");itemC->setData("Tip B");itemC->setData("Help C");root->setChild(0, 0, itemA);//itemA、itemB、itemC都是new出來的,這里將數據項root->setChild(0, 1, itemB);//加入模型的同時也相當于指定了父組件,不會造成內存泄漏root->setChild(1, 0, itemC);} void MainWindow::initTableModel() {m_tableView.resize(300,100);m_tableView.move(10,10);m_tableView.setParent(this); } MainWindow::~MainWindow() {}

main.cpp:

#include <QtGui/QApplication> #include "MainWindow.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);MainWindow w;w.show();return a.exec(); }

運行結果如下:

我們會發現結果無法正常顯示,為了使數據能夠正常顯示,我們需要引入數據角色的概念:

  • 模型中的數據在視圖中的用途(顯示方式)可能不同。
  • 模型必須為數據設置特定數據角色(數據屬性)。
  • 數據角色用于提示視圖數據的作用。
  • 數據角色是不同視圖以統一風格顯示數據的標準。

Qt中的數據角色定義:

數據角色的意義:

  • 定義了數據在特定系統下的標準用途。
  • 不同的視圖可以通過相同標準顯示數據。

注意:數據角色只是一個附加的屬性,這個屬性代表推薦的數據顯示方式。不同的視圖完全可以自由解析或者忽略數據的角色信息。

更改后的代碼如下:
Widget.h:

#ifndef WIDGET_H #define WIDGET_H#include <QtGui/QWidget> #include <QTableView> #include <QListView> #include <QTreeView> #include <QStandardItemModel>class Widget : public QWidget {Q_OBJECTQStandardItemModel m_model;QTableView m_tableView;QListView m_listView;QTreeView m_treeView;void initModel();void initView(); public:Widget(QWidget *parent = 0);~Widget(); };#endif // WIDGET_H

Widget.cpp:

#include "Widget.h" #include <QStandardItem>Widget::Widget(QWidget *parent): QWidget(parent, Qt::WindowContextHelpButtonHint) {initModel();initView();m_tableView.setModel(&m_model);m_listView.setModel(&m_model);m_treeView.setModel(&m_model); }void Widget::initModel() {QStandardItem* root = m_model.invisibleRootItem();QStandardItem* itemA = new QStandardItem();QStandardItem* itemB = new QStandardItem();QStandardItem* itemC = new QStandardItem();QStandardItem* itemChild = new QStandardItem();itemA->setData("A", Qt::DisplayRole);itemA->setData("Tip A", Qt::ToolTipRole);itemA->setData("Help A", Qt::WhatsThisRole);itemB->setData("B", Qt::DisplayRole);itemB->setData("Tip B", Qt::ToolTipRole);itemC->setData("C", Qt::DisplayRole);itemC->setData("Tip C", Qt::ToolTipRole);itemC->setData("Help C", Qt::WhatsThisRole);itemChild->setData("Child", Qt::DisplayRole);itemChild->setData("Tip Child", Qt::ToolTipRole);itemChild->setData("Help Child", Qt::WhatsThisRole);itemC->setChild(0, 0, itemChild);root->setChild(0, 0, itemA);root->setChild(0, 1, itemB);root->setChild(1, 0, itemC); }void Widget::initView() {m_tableView.setParent(this);m_tableView.move(10, 10);m_tableView.resize(300, 100);m_listView.setParent(this);m_listView.move(10, 120);m_listView.resize(300, 100);m_treeView.setParent(this);m_treeView.move(10, 230);m_treeView.resize(300, 100); }Widget::~Widget() {}

main.cpp:

#include <QtGui/QApplication> #include "Widget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }

運行結果如下:


參考資料:

  • QT實驗分析教程
  • 總結

    以上是生活随笔為你收集整理的Qt中的模型视图设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。