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_NAMESPACE

class MainWindow : public QMainWindow {
Q_OBJECT

public:
    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版 (霍亚飞 著)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EasyExcel批量读取Excel文件数据导入到MySQL表中

1、EasyExcel简介 官网&#xff1a;EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 2、代码实战 首先引入jar包 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</v…

基于FPGA的千兆以太网设计(1)----大白话解释什么是以太网

1、什么是以太网? 还记得初学以太网的时候,我就被一大堆专业名词给整懵了:什么以太网,互联网,MAC,IP,局域网,万维网,网络分层模型等等等等。慢着!我学的不是以太网吗?怎么出来这么一大堆东西? 啊!以太网究竟是什么?别急,我接下来就尽量用通俗的大白话来给你解释…

Phpstudy 2018 之xhcms搭建

1、由于直接访问根目录无法进入网站 2、所以采用搭建网站&#xff0c;第一使用系统服务模式、选择php-5.4.45Apache模式 3、网站域名为本地ip地址或者127.0.0.1、端口8085 4、浏览器输入127.0.0.1:8085直接转到系统安装 5、返回输入127.0.0.1:8085&#xff0c;成功进入网站

前端JS特效第36波:jQ多种相册切换效果

jQ多种相册切换效果&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"h…

Mac安装stable diffusion 工具

文章目录 1.安装 Homebrew2.安装 stable diffusion webui 的依赖3.下载 stable diffusion webui 代码4.启动 stable diffusion webui 本体5.下载模型6.这里可能会遇到一个clip-vit-large-patch14报错 参考&#xff1a;https://brew.idayer.com/install/stable-diffusion-webui/…

[ruby on rails]部署时候产生ActiveRecord::PreparedStatementCacheExpired错误的原因及解决方法

一、问题&#xff1a; 有时在 Postgres 上部署 Rails 应用程序时&#xff0c;可能会看到 ActiveRecord::PreparedStatementCacheExpired 错误。仅当在部署中运行迁移时才会发生这种情况。发生这种情况是因为 Rails 利用 Postgres 的缓存准备语句(PreparedStatementCache)功能来…

数学建模·非线性规划

整型规划 适用于一个变量或多个变量的值只能是整型的情况 整形规划的分类 0-1背包问题 对于一个物品来说&#xff0c;只有选和不选两种情况 表现为单下标&#xff0c;单变量问题 例&#xff1a;建设学校问题 对于每个学校来说只有选和不选两种情况&#xff0c;在数学上我们用…

内网信息收集——MSF信息收集浏览器记录配置文件敏感信息

文章目录 一、配置文件敏感信息收集二、浏览器密码&记录三、MSF信息收集 域控&#xff1a;windows server 2008 域内机器&#xff1a;win7 攻击机&#xff1a;kali 就是红日靶场&#xff08;一&#xff09;的虚拟机。 一、配置文件敏感信息收集 使用searchall64.exe&#…

Windows11终端winget配置

一、工具安装 Windows11是自带该工具的&#xff0c;如果wind10&#xff0c;可以找应用商店和GitHub上进行下载。 安装地址使用 winget 工具安装和管理应用程序 | Microsoft Learn 发布地址 Releases microsoft/terminal GitHub 二、无法使用问题排错 在命令行界面出现以…

【python学习】多线程编程的背景、定义、特点、优缺点、使用场景和示例以及和单线程的区别

引言 随着计算机技术的发展&#xff0c;多核处理器已经成为了主流,为了充分利用多核处理器带来的并行计算能力&#xff0c;提高程序的执行效率和响应速度&#xff0c;多线程编程变得尤为重要 Python作为一种高级编程语言&#xff0c;提供了多线程编程的支持&#xff0c;允许开发…

电子期刊制作实战教程:从零开始制作

​随着互联网的普及&#xff0c;电子期刊已经成为了信息传递的重要载体。它以便捷、环保、互动性强等特点受到了越来越多人的青睐。那么&#xff0c;如何从零开始制作一份吸引人的电子期刊呢&#xff1f; 1.要制作电子杂志,首先需要选择一款适合自己的软件。比如FLBOOK在线制作…

链表(一)----单链表,链表的删除,链表的合并,链表的划分,头节点

官网地址&#xff1a;https://www.dhcode.cn/p/t_pc/goods_pc_detail/goods_detail/term_624bd804b3d39_Ac0g7V?fromH5true&type3&channel_id&pro_idterm_624bd804b3d39_Ac0g7V 本内容大部分从中截图 讲了三个力扣题&#xff1a;203&#xff0c;21&#xff0c;8…

【postgresql】锁

PostgreSQL 提供了多种锁模式来控制对表和行的并发访问&#xff0c;以确保数据的一致性和完整性。这些锁模式包括表级锁和行级锁&#xff0c;它们可以由应用程序显式控制&#xff0c;也可以在执行大多数 PostgreSQL 命令时自动获取。 锁类型 PostgreSQL类型的锁包括&#xff…

2024-07-14 Unity插件 Odin Inspector1 —— 插件介绍

文章目录 1 介绍2 模块3 学习目的 1 介绍 ​ Odin Inspector 是 Unity 的一个插件&#xff0c;拥有强大、自定义和用户友好的编辑器&#xff0c;而无需编写任何自定义编辑器代码&#xff0c;使得编程过程中的数据可视化更容易实现。 ​ 具体功能包括&#xff1a; 更舒适美观…

网络(二)——套接字编程

文章目录 理解源IP地址和目的IP地址认识端口号认识TCP/UDP协议网络字节序socket编程接口socket 常见APIsockaddr结构 理解源IP地址和目的IP地址 在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址&#xff1b; 源IP即发送方的地址&#xff0c;目的IP即接受方的…

创建yaml文件并读取

yaml文件可以存放token数据&#xff0c;那怎么操作存放并读取呢&#xff1f; 1、创建yaml文件 1、导入类库 import yaml 注意要导入的类库&#xff0c;在解释器中叫pyaml 2、创建文件 #创建yaml文件 yamlfileopen("testdata.yaml",w,encodingutf-8) 3、设置数据…

PostgreSQL 中如何解决因频繁的小事务导致的性能下降?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中解决因频繁小事务导致性能下降的方法 PostgreSQL 中解决因频繁小事务导致性能下降的方法…

电气工程VR虚拟仿真实训平台以趣味化方式增强吸引力

在工业4.0时代和教育信息化的双重推动下&#xff0c;我们致力于推动实训课件的跨界合作与共创。VR实训课件不仅促进了不同领域、不同行业之间的紧密合作&#xff0c;更让学习变得生动直观。我们凭借3D技术生动、直观、形象的特点&#xff0c;开发了大量配套3D教材&#xff0c;让…

如何允许从互联网(外网)进入路由器管理页面

1.绑定UDP端口 操作如图所示&#xff1a; 2.然后再绑定虚拟换回网卡 3.然后再把出端口编号设置成为2 使他成为一个双向输入输出具体操作如图所示&#xff1a; 4.进入防火墙然后再启动防火墙进行端口配置&#xff1a; 1.进入端口g0/0/0配置ip地址&#xff08;注意配置的ip地…

游戏热更新——AssetBundle

AssetBundle AssetBundle的定义与使用 AssetBundle是一个压缩包包含模型、贴图、预制体、声音、甚至是整个场景&#xff0c;可以在游戏运行的时候被加载 AssetBundle自身保存着相互的依赖关系 压缩包可以使用LZMA和LZ4压缩算法&#xff0c;减少包大小&#xff0c;更快的进行网…