Qt MV架構-視圖類

一、基本概念

在MV架構中,視圖包含了模型中的數據項,并將它們呈現給用戶。數據項的表示方法,可能和數據項在存儲時用的數據結構完全不同。

這種內容與表現分離之所以能夠實現,是因為使用了

  1. QAbstractItemModel提供的一個標準模型接口;
  2. 一個標準視圖接口;
  3. 模型索引所提供的一種通用的方法;

來表示數據。

視圖通常管理從模型獲取數據的整體布局。視圖可以自己渲染獨立的數據項,也可以使用委托來處理渲染和編輯。

1. 項目導航和選擇行為

除了呈現數據,視圖還處理項目間的導航,以及項目選擇的某些方面。
表1和表2分別羅列了視圖中的選擇行為(QAbstractItemView::SelectionBehaviour)和選擇模式(QAbstractItemView::SelectionMode

表1 視圖類的選擇行為(QAbstractItemView::SelectionBehaviour)

常量描述
QAbstractItemView::SelectItems選擇單個項目
QAbstractItemView::SelectRows只選擇行
QAbstractItemView::SelectColumns只選擇列

表2 視圖類的選擇模式

常量描述
QAbstractItemView::SingleSelection當用戶選擇一個項目,索所有已選擇的項目將成為未選擇態,而且用戶無法在已經選擇的項目上單擊來取消選擇。
QAbstractItemView::ContiguousSelection如果用戶在單擊一個項目的同時按著Shift鍵,所有在當前和單擊項目之間的項目都將被選擇或者取消選擇,這依賴于被單擊項目的狀態。
QAbstractItemView::ExtendedSelection具有ConiguousSelection的特性,而且還可以按著Ctrl鍵進行不連續的選擇。
QAbstractItemView::MultiSelection用戶選擇一個項目時,不影響其他已經選擇的項目。
QAbstractItemView::NoSelection項目無法被選擇。

對于一些視圖,例如QTreeViewQTreeView,在顯示項目的同時還可以顯示表頭。這是通過QHeaderView類來實現的,它們使用QAbstractItemModel::headerData()從模型中獲取數據,然后一般使用一個標簽來顯示表頭信息。可以通過子類化QHeaderView來設置標簽的顯示。

Qt中已經提供了QListView,QTableViewQTreeView這三個現成的視圖,不過都是使用規范的格式顯示數據。
如果想要實現條形圖、餅狀圖等特殊顯示方式,需要重新實現視圖。

二、項目選擇

MV架構對項目的選擇提供了非常方便的處理方法。
視圖中被選擇的項目的信息,存儲在一個QItemSelectionModel實例中,這樣被選擇的項目模型索引便保持在一個獨立的模型中,與所有的視圖都是獨立的。

當在一個模型上設置多個視圖時,就可以實現在多個視圖之間共享選擇

選擇由選擇范圍指定,只需要記錄每一個選擇范圍開始和結束的模型索引即可,非連續的選擇可以使用多個選擇范圍來描述。
選擇可以看作是在選擇模型中保存的一個模型索引集合,最近的項目選擇被稱為當前選擇。

1. 當前項目、被選擇項目

視圖中總是有一個當前項目和一個被選擇的項目,兩者是獨立的狀態。

在同一時間,一個項目可以既是當前項目,同時也是被選擇項目。視圖負責確保總是有一個項目作為當前項目來實現鍵盤導航。

表3 當前項目和被選擇的項目的區別

當前項目被選擇的項目
只能有一個當前項目被選擇的項目
使用鍵盤導航鍵或者鼠標按鍵可以改變當前項目項目是否處于被選擇狀態,取決于幾個預先定義好的模式,例如單項選擇、多重選擇等。
如果按下F2鍵或者雙擊都可以編輯當前項目當前項目可以通過指定一個范圍來一起被使用
當前項目會顯示焦點矩形被選擇的項目會使用選擇矩形來表示

當操作選擇時,可以將QItemnSelectionModel看作一個項目模型中所有項目的選擇狀態的一個記錄。
一旦設置了一個選擇模型,所有的項目集合都可以被選擇、取消選擇或者切換選擇狀態,而不需要知道哪一個項目已經被選擇了。所有被選擇項目的索引都可以被隨時進行檢索,其他的組件也可以通過信號和槽機制來獲取選擇模型的改變信息。

2. 選擇模型

標準的視圖類中提供了默認的選擇模型,可以在大多數的應用中直接使用。
屬于一個視圖的選擇模型可以使用這個視圖的selectionModel()函數獲得,而且還可以在多個視圖之間使用setSelectionModel()函數來共享該選擇模型,所以一般是不需要重新構建一個選擇模型的。

三、代碼實例

實現兩個視圖共享數據模型和選擇模型。

在這里插入圖片描述
MainWindow.h

#pragma once#include <QMainWindow>class QTableView;
class QItemSelection;
class QModelIndex;QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow {
Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow() override;
public slots:void getCurrentItemData();void toggleSelection();void updateSelection(const QItemSelection &selected, const QItemSelection &deselected);void changeCurrent(const QModelIndex &current, const QModelIndex &previous);
private:Ui::MainWindow *ui;QTableView* tableView;QTableView* tableView2;
};

MainWindow.cpp

#include "mainwindow.h"
#include "ui_MainWindow.h"
#include <QStandardItemModel>
#include <QTableView>
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);auto model = new QStandardItemModel(7, 4, this);for (int row = 0; row < 7; ++row) {for (int column = 0; column < 4; ++column) {auto item = new QStandardItem(QString("%1").arg(row * 4 + column));model->setItem(row, column, item);}}tableView = new QTableView;tableView->setModel(model);setCentralWidget(tableView);QItemSelectionModel* selectionModel = tableView->selectionModel();QModelIndex topLeft;QModelIndex bottomRight;topLeft = model->index(1,1,QModelIndex());bottomRight = model->index(5,2,QModelIndex());QItemSelection selection(topLeft, bottomRight);selectionModel->select(selection, QItemSelectionModel::Toggle);ui->menubar->addAction(tr("當前項目"), this, &MainWindow::getCurrentItemData);ui->menubar->addAction(tr("切換選擇"), this, &MainWindow::toggleSelection);connect(selectionModel, &QItemSelectionModel::selectionChanged,this, &MainWindow::updateSelection);connect(selectionModel, &QItemSelectionModel::currentChanged,this,&MainWindow::changeCurrent);{tableView2 = new QTableView;tableView2->setWindowTitle("tableView2");tableView2->resize(400,300);tableView2->setModel(tableView->model());tableView2->setSelectionModel(tableView->selectionModel());tableView2->show();}
}MainWindow::~MainWindow() {delete ui;delete tableView2;
}void
MainWindow::getCurrentItemData()
{qDebug() << tr("當前項目內容")<< tableView->selectionModel()->currentIndex().data().toString();
}void
MainWindow::toggleSelection()
{QModelIndex topLeft     = tableView->model()->index(0,0,QModelIndex());QModelIndex bottomRight = tableView->model()->index(tableView->model()->rowCount(QModelIndex()) - 1,tableView->model()->columnCount(QModelIndex()) - 1,QModelIndex());QItemSelection curSelection(topLeft, bottomRight);tableView->selectionModel()->select(curSelection, QItemSelectionModel::Toggle);
}void
MainWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected)
{QModelIndex index;QModelIndexList list = selected.indexes();foreach(index, list){QString text = QString("%1,%2").arg(index.row()).arg(index.column());tableView->model()->setData(index, text);}list = deselected.indexes();foreach(index, list){tableView->model()->setData(index, "");}
}void
MainWindow::changeCurrent(const QModelIndex &current, const QModelIndex &previous)
{qDebug() << tr("move(%1,%2) to (%3,%4)").arg(previous.row()).arg(previous.column()).arg(current.row()).arg(current.column());
}

參考資料: Qt Creator快速入門第2版 (霍亞飛 著)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/44828.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44828.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44828.shtml

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

相關文章

`nmap`模塊是一個用于與Nmap安全掃描器交互的庫

在Python中&#xff0c;nmap模塊是一個用于與Nmap安全掃描器交互的庫。Nmap&#xff08;Network Mapper&#xff09;是一個開源工具&#xff0c;用于發現網絡上的設備和服務。雖然Python的nmap模塊可能不是官方的Nmap庫&#xff08;因為Nmap本身是用C/C編寫的&#xff09;&…

基于JavaSpringBoot+Vue+uniapp微信小程序校園宿舍管理系統設計與實現

基于JavaSpringBootVueuniapp微信小程序實現校園宿舍管理系統設計與實現 目錄 第一章 緒論 1.1 研究背景 1.2 研究現狀 1.3 研究內容 第二章 相關技術介紹 2.1 Java語言 2.2 HTML網頁技術 2.3 MySQL數據庫 2.4 Springboot 框架介紹 2.5 VueJS介紹 2.6 ElementUI介紹…

視頻轉換、提取音頻、視頻加水印、視頻去水印、音頻轉換、分割合并壓縮等,批量還幾乎免費

「想轉就轉視頻音頻助手」免費版來襲&#xff01; 在數字化時代&#xff0c;視頻和音頻處理已成為我們日常生活的一部分。無論是制作個人視頻博客、編輯家庭影片&#xff0c;還是處理音頻文件&#xff0c;我們都在尋找一個強大而易于使用的解決方案。今天&#xff0c;我要向您…

基于大語言模型(LLM)的合成數據生成、策展和評估的綜述

節前&#xff0c;我們星球組織了一場算法崗技術&面試討論會&#xff0c;邀請了一些互聯網大廠朋友、參加社招和校招面試的同學。 針對算法崗技術趨勢、大模型落地項目經驗分享、新手如何入門算法崗、該如何準備、面試常考點分享等熱門話題進行了深入的討論。 合集&#x…

【JVM實戰篇】內存調優:內存泄露危害+內存監控工具介紹+內存泄露原因介紹

文章目錄 內存調優內存溢出和內存泄漏內存泄露帶來什么問題內存泄露案例演示內存泄漏的常見場景場景一場景二 解決內存溢出的方法常用內存監控工具Top命令優缺點 VisualVM軟件、插件優缺點監控本地Java進程監控服務器的Java進程&#xff08;生產環境不推薦使用&#xff09; Art…

【圖解大數據技術】流式計算:Spark Streaming、Flink

【圖解大數據技術】流式計算&#xff1a;Spark Streaming、Flink 批處理 VS 流式計算Spark StreamingFlinkFlink簡介Flink入門案例Streaming Dataflow Flink架構Flink任務調度與執行task slot 和 task EventTime、Windows、WatermarksEventTimeWindowsWatermarks 批處理 VS 流式…

如何查找電腦的MAC地址

一. 什么是mac地址&#xff1f; mac地址本質上幫助我們連接到我們遇到的大多數本地網絡。每個網絡適配器通常由網絡接口??控制器(NIC) 制造商分配一個唯一的 mac 地址。 二. 如何查找mac地址 1.點擊網絡和Internet設置 2.點擊WLAN點擊硬件屬性 3.即可查看mac地址

智慧城市3d數據可視化系統提升信息匯報的時效和精準度

在信息大爆炸的時代&#xff0c;數據的力量無可估量。而如何將這些數據以直觀、高效的方式呈現出來&#xff0c;成為了一個亟待解決的問題。為此&#xff0c;我們推出了全新的3D可視化數據大屏系統&#xff0c;讓數據“躍然屏上”&#xff0c;助力您洞察先機&#xff0c;決勝千…

從零開始實現大語言模型(五):縮放點積注意力機制

1. 前言 縮放點積注意力機制(scaled dot-product attention)是OpenAI的GPT系列大語言模型所使用的多頭注意力機制(multi-head attention)的核心,其目標與前文所述簡單自注意力機制完全相同,即輸入向量序列 x 1 , x 2 , ? ? , x n x_1, x_2, \cdots, x_n x

pytorch訓練的時候 shm共享內存不足,導致訓練停止

1.查看shm情況 df -h /dev/shm內存已經滿了&#xff0c;因為之前訓練多次訓練意外停止到shm中的緩存不能及時被清理 2、手動清理shm 依然沒被釋放 3、查看關聯的進程&#xff0c;一個一個kill lsof |grep deletedkill -9 46619 44618 44617 。。。。。4、搞定

Spring @Scheduled學習

一. Jdk中的定時任務 我們平時在 Spring 項目中會使用 Scheduled 開啟定時任務&#xff1b; jdk 中其實也提供了定時任務線程池 ScheduledThreadPool&#xff0c;我們可以直接通過 Executors 工具類獲取&#xff1b; // 創建了核心線程數為 2 的 ScheduledThreadPool 對象 S…

ROS2 + 科大訊飛 初步實現機器人語音控制

環境配置&#xff1a; 電腦端&#xff1a; ubuntu22.04實體機作為上位機 ROS版本&#xff1a;ros2-humble 實體機器人&#xff1a; STM32 思嵐A1激光雷達 科大訊飛語音SDK 訊飛開放平臺-以語音交互為核心的人工智能開放平臺 實現步驟&#xff1a; 1. 下載和處理科大訊飛語音模…

開發指南048-前端模塊版本

平臺前端框架內置了一個文件version.vue <template> <div> <br> 應用名稱: {{name}} <br> 當前版本&#xff1a;{{version}} <br> 服務網關: {{gateway}} </div> </template> <scrip…

qt 創建一個包含兩按鈕,且安裝和自定義控件間沒有間距

在 Qt 中創建一個包含兩個按鈕且按鈕之間沒有間距的自定義控件&#xff0c;你可以使用 QHBoxLayout 或 QVBoxLayout&#xff08;取決于你希望按鈕是水平排列還是垂直排列&#xff09;&#xff0c;并設置布局的間距為 0。以下是一個簡單的示例&#xff0c;展示了如何創建一個水平…

Dataset for Stable Diffusion

1.Dataset for Stable Diffusion 筆記來源&#xff1a; 1.Flickr8k數據集處理 2.處理Flickr8k數據集 3.Github&#xff1a;pytorch-stable-diffusion 4.Flickr 8k Dataset 5.dataset_flickr8k.json 1.1 Dataset 采用Flicker8k數據集&#xff0c;該數據集有兩個文件&#xff…

Node.js_mongodb用戶名和密碼操作

mongodb用戶名和密碼操作 查看用戶密碼創建管理員用戶和密碼mongodb的目標是實現快速簡單部署,所以存在很多安全問題 默認配置下沒有用戶和密碼,無需身份驗證即可登錄,不像mysql那樣需要登錄才能操作數據庫本身安全問題:升級3.0以上版本查看用戶密碼 密碼是加密存儲的,并且…

前端工程化10-webpack靜態的模塊化打包工具之各種loader處理器

9.1、案例編寫 我們創建一個component.js 通過JavaScript創建了一個元素&#xff0c;并且希望給它設置一些樣式&#xff1b; 我們自己寫的css,要把他加入到Webpack的圖結構當中&#xff0c;這樣才能被webpack檢測到進行打包&#xff0c; style.css–>div_cn.js–>main…

速盾:ddos高防ip哪里好用?

隨著互聯網的飛速發展&#xff0c;DDoS攻擊問題逐漸突出。DDoS攻擊是一種通過在網絡上創建大量請求&#xff0c;使目標網絡或服務器過載而無法正常工作的攻擊方式。為了應對DDoS攻擊&#xff0c;提高網絡的安全性和穩定性&#xff0c;使用高防IP成為了一種常見的解決辦法。 DD…

Flower花所比特幣交易及交易費用科普

在加密貨幣交易中&#xff0c;選擇一個可靠的平臺至關重要。Flower花所通過提供比特幣交易服務脫穎而出。本文將介紹在Flower花所進行比特幣交易的基礎知識及其交易費用。 什么是Flower花所&#xff1f; Flower花所是一家加密貨幣交易平臺&#xff0c;為新手和資深交易者提供…

【C++】開源:drogon-web框架配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 這篇文章主要介紹drogon-web框架配置使用。 無專精則不能成&#xff0c;無涉獵則不能通。——梁啟超 歡迎來到我的博客&#xff0c;一起學習&#xff0c;共同進步。 喜歡的朋友可以關注一下&#xff0c;…