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.mzph.cn/web/44828.shtml

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

相关文章

基于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介绍…

基于大语言模型(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;决胜千…

pytorch训练的时候 shm共享内存不足,导致训练停止

1.查看shm情况 df -h /dev/shm内存已经满了&#xff0c;因为之前训练多次训练意外停止到shm中的缓存不能及时被清理 2、手动清理shm 依然没被释放 3、查看关联的进程&#xff0c;一个一个kill lsof |grep deletedkill -9 46619 44618 44617 。。。。。4、搞定

ROS2 + 科大讯飞 初步实现机器人语音控制

环境配置&#xff1a; 电脑端&#xff1a; ubuntu22.04实体机作为上位机 ROS版本&#xff1a;ros2-humble 实体机器人&#xff1a; STM32 思岚A1激光雷达 科大讯飞语音SDK 讯飞开放平台-以语音交互为核心的人工智能开放平台 实现步骤&#xff1a; 1. 下载和处理科大讯飞语音模…

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…

前端工程化10-webpack静态的模块化打包工具之各种loader处理器

9.1、案例编写 我们创建一个component.js 通过JavaScript创建了一个元素&#xff0c;并且希望给它设置一些样式&#xff1b; 我们自己写的css,要把他加入到Webpack的图结构当中&#xff0c;这样才能被webpack检测到进行打包&#xff0c; style.css–>div_cn.js–>main…

Flower花所比特币交易及交易费用科普

在加密货币交易中&#xff0c;选择一个可靠的平台至关重要。Flower花所通过提供比特币交易服务脱颖而出。本文将介绍在Flower花所进行比特币交易的基础知识及其交易费用。 什么是Flower花所&#xff1f; Flower花所是一家加密货币交易平台&#xff0c;为新手和资深交易者提供…

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

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍drogon-web框架配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…

Linux系统编程-线程同步详解

线程同步是指多个线程协调工作&#xff0c;以便在共享资源的访问和操作过程中保持数据一致性和正确性。在多线程环境中&#xff0c;线程是并发执行的&#xff0c;因此如果多个线程同时访问和修改共享资源&#xff0c;可能会导致数据不一致、竞态条件&#xff08;race condition…

【密码学】消息认证

你发送给朋友一条消息&#xff08;内容&#xff1a;明天下午来我家吃饭&#xff09;&#xff0c;这一过程中你不想让除你朋友以外的人看到消息的内容&#xff0c;这就叫做消息的机密性&#xff0c;用来保护消息机密性的方式被叫做加密机制。 现在站在朋友的视角&#xff0c;某一…

使用PyQt5实现添加工具栏、增加SwitchButton控件

前言&#xff1a;通过在网上找到的“电池电压监控界面”&#xff0c;学习PyQt5中添加工具栏、增加SwitchButton控件&#xff0c;在滑块控件右侧增加文本显示、设置界面背景颜色、修改文本控件字体颜色等。 1. 上位机界面效果展示 网络上原图如下&#xff1a; 自己使用PyQt5做…

【Linux】多线程_3

文章目录 九、多线程3. C11中的多线程4. 线程的简单封装 未完待续 九、多线程 3. C11中的多线程 Linux中是根据多线程库来实现多线程的&#xff0c;C11也有自己的多线程&#xff0c;那它的多线程又是怎样的&#xff1f;我们来使用一些C11的多线程。 Makefile&#xff1a; te…

Linux - 探索命令行

探索命令行 Linux命令行中的命令使用格式都是相同的: 命令名称 参数1 参数2 参数3 ...参数之间用任意数量的空白字符分开. 关于命令行, 可以先阅读一些基本常识. 然后我们介绍最常用的一些命令: ls用于列出当前目录(即"文件夹")下的所有文件(或目录). 目录会用蓝色…

CSIP-FTE考试专业题

靶场下载链接&#xff1a; https://pan.baidu.com/s/1ce1Kk0hSYlxrUoRTnNsiKA?pwdha1x pte-2003密码&#xff1a;admin123 centos:root admin123 解压密码&#xff1a; PTE考试专用 下载好后直接用vmware打开&#xff0c;有两个靶机&#xff0c;一个是基础题&#x…

【CTF-Crypto】数论基础-02

【CTF-Crypto】数论基础-02 文章目录 【CTF-Crypto】数论基础-021-16 二次剩余1-20 模p下-1的平方根*1-21 Legendre符号*1-22 Jacobi符号*2-1 群*2-2 群的性质2-3 阿贝尔群*2-4 子群2-11 群同态2-18 原根2-21 什么是环2-23 什么是域2-25 子环2-26 理想2-32 多项式环 1-16 二次剩…

打造智慧校园德育管理,提升学生操行基础分

智慧校园的德育管理系统内嵌的操行基础分功能&#xff0c;是对学生日常行为规范和道德素养进行量化评估的一个创新实践。该功能通过将抽象的道德品质转化为具体可量化的指标&#xff0c;如遵守纪律、尊师重道、团结协作、爱护环境及参与集体活动的积极性等&#xff0c;为每个学…