QT Mode/View之View

news2024/9/27 9:30:27

目录

概念

使用已存在的视图

使用模型

使用模型的多个视图

处理元素的选择

视图间共享选择


概念

在模型/视图架构中,视图从模型中获取数据项并将它们呈现给用户。数据的表示方式不必与模型提供的数据表示形式相似,而且可能与用于存储数据项的底层数据结构完全不同。

通过使用QAbstractItemModel提供的标准模型接口和QAbstractItemView提供的标准视图接口,以及使用通用方式表示数据项的模型索引,实现了内容与表现的分离。视图通常管理从模型中获得的数据的总体布局。它们可以自己渲染单个数据项,或者使用委托来处理渲染和编辑功能。

除了显示数据,视图还处理项目之间的导航,以及项目选择的一些方面。这些视图还实现了基本的用户界面功能,例如上下文菜单和拖放。视图可以为项目提供默认的编辑功能,也可以与委托一起提供自定义编辑器。

可以在没有模型的情况下构建视图,但是必须提供模型才能显示有用的信息。视图通过使用可以为每个视图单独维护或在多个视图之间共享的选择项来跟踪用户选择的项目。

有些视图,如QTableView和QTreeView,显示标题和项目。这些也由一个视图类QHeaderView实现。标题通常访问包含它们的视图的同一个模型。它们使用QAbstractItemModel::headerData()函数从模型中获取数据,并且通常以标签的形式显示标题信息。新的标题可以从QHeaderView类子类化,为视图提供更专门的标签。

使用已存在的视图

Qt提供了三个可用的视图类,它们以大多数用户熟悉的方式呈现模型中的数据。QListView可以将模型中的项目显示为简单的列表,或者以经典图标视图的形式显示。QTreeView将模型中的项目显示为列表的层次结构,允许以紧凑的方式表示深度嵌套结构。QTableView以表格的形式呈现模型中的项目,很像电子表格应用程序的布局。

上面显示的标准视图的默认行为应该足以满足大多数应用程序。它们提供基本的编辑功能,并可以进行定制以适应更专业的用户界面的需求。

使用模型

我们将创建的字符串列表模型作为示例模型,在其中设置一些数据,并构建一个视图来显示模型的内容。这些都可以在一个函数中完成:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // Unindented for quoting purposes:
    QStringList numbers;
    numbers << "One" << "Two" << "Three" << "Four" << "Five";

    QAbstractItemModel *model = new StringListModel(numbers);

注意,StringListModel被声明为QAbstractItemModel。这允许我们使用模型的抽象接口,并确保代码仍然有效,即使我们将字符串列表模型替换为不同的模型。

QListView提供的列表视图足以显示string列表模型中的项目。我们使用下面的代码来构建视图和建立模型:

QListView *view = new QListView;
view->setModel(model);

视图按正常方式显示:

    view->show();
    return app.exec();
}

视图渲染模型的内容,通过模型的接口访问数据。当用户试图编辑项时,视图使用默认委托来提供编辑器部件。

上图显示了QListView如何表示字符串列表模型中的数据。由于模型是可编辑的,视图自动允许使用默认委托编辑列表中的每一项。

使用模型的多个视图

为同一个模型提供多个视图,只需为每个视图设置相同的模型即可。在下面的代码中,我们创建了两个表视图,每个都使用了我们为这个例子创建的相同的简单表模型:

    QTableView *firstTableView = new QTableView;
    QTableView *secondTableView = new QTableView;

    firstTableView->setModel(model);
    secondTableView->setModel(model);

在模型/视图架构中使用信号和槽意味着对模型的更改可以传播到所有附加的视图,确保我们始终可以访问相同的数据,无论使用的是哪个视图。

上图显示了同一个模型的两个不同视图,每个视图都包含一些选中的项目。尽管来自模型的数据在整个视图中一致地显示,但每个视图都维护自己的内部选择模型。这在某些情况下可能有用,但对于许多应用程序来说,共享选择模型是可取的。

选择模型

在视图中处理元素选择的机制由QItemSelectionModel类提供。所有的标准视图都默认构建自己的选择模型,并以正常的方式与它们交互。视图使用的选择模型可以通过selectionModel()函数获得,而替换选择模型可以通过setSelectionModel()指定。当我们想为同一个模型数据提供多个一致的视图时,控制视图使用的选择模型的能力很有用。

一般来说,除非是模型或视图的子类化,否则不需要直接操作选择的内容。不过,如果需要的话,选择模型的接口也是可以访问的,参考:处理Item视图中的选择。

视图间共享选择

虽然视图类默认提供自己的选择模型很方便,但当我们在同一个模型上使用多个视图时,通常希望模型的数据和用户的选择在所有视图中都保持一致。由于视图类允许替换它们的内部选择模型,我们可以使用以下代码实现视图之间的统一选择:

secondTableView->setSelectionModel(firstTableView->selectionModel());

第二个视图被赋予第一个视图的选择模型。现在,两个视图都在相同的选择模型上操作,保持数据和选择项同步。

在上面的示例中,使用两个相同类型的视图来显示相同模型的数据。但是,如果使用了两种不同类型的视图,则所选项目在每个视图中的表示可能非常不同;例如,表视图中的连续选择可以表示为树视图中突出显示的项目的碎片集。

处理Item视图中的选择

概念

item视图类中使用的选择模型提供了基于模型/视图体系结构的选择的一般描述。尽管操作选择的标准类对所提供的项目视图来说已经足够了,但是选择模型允许您创建专门的选择模型,以满足您自己的项目模型和视图的需求。

关于视图中所选项的信息存储在QItemSelectionModel类的一个实例中。它为单个模型中的项维护模型索引,并且独立于任何视图。由于一个模型可以有多个视图,因此可以在视图之间共享选择,从而允许应用程序以一致的方式显示多个视图。

选择由选择范围组成。这些方法通过仅记录每个选定项范围的起始和结束模型索引来有效地维护关于大量选择项的信息。通过使用多个选择范围来描述选择,构建非连续的选择项集;

选择应用于选择模型持有的模型索引集合。最近选择的应用项称为当前选择。这种选择的效果即使在应用后也可以通过使用某些类型的选择命令进行修改。本节稍后将讨论这些内容。

当前项目和已选项目

在视图中,总是有一个当前项和一个选定项——两个独立的状态。一个项目可以是当前项目,同时选择。视图负责确保始终有一个当前项,例如,键盘导航需要一个当前项。

下表突出显示了当前项和选定项之间的差异。

Current ItemSelected Items
当前项只能有一个。可以有多个选择项。
当前项目将随着按键导航或鼠标按钮点击而改变。当用户与项目交互时,项目的选择状态是被设置还是未设置,这取决于几种预定义的模式——例如,单选择、多选择等。
如果按下编辑键F2或双击项目,当前项目将被编辑(前提是启用编辑)。当前元素可以和锚点一起使用,以指定选择或取消选择的范围(或两者的结合)。
当前项由焦点矩形表示。选中的项目用选择矩形表示。

在操作选择时,通常可以将QItemSelectionModel视为一个项目模型中所有项目的选择状态的记录。一旦建立了选择模型,就可以选择、取消选择元素,或者切换它们的选择状态,而不需要知道哪些元素已经被选择了。所有选中项的索引可以随时被获取,并且可以通过信号和槽机制通知其他组件选择模型的变化。

使用选择模型

标准视图类提供了默认的选择模型,可以在大多数应用程序中使用。属于一个视图的选择模型可以使用视图的selectionModel()函数获得,并通过setSelectionModel()在多个视图之间共享,因此通常不需要构造新的选择模型。

通过指定一个模型和一对QItemSelection的模型索引来创建一个选择。这使用索引来引用给定模型中的项,并将它们解释为选定项块中的左上角和右下角项。要将选择应用于模型中的项目,需要将选择提交到选择模型;这可以通过多种方式实现,每种方式对选择模型中已经存在的选择有不同的影响。

选择项目

为了演示selection的一些主要特性,我们构建一个自定义表模型的实例,其中共有32个元素,然后打开一个表视图,查看其中的数据:

    TableModel *model = new TableModel(8, 4, &app);

    QTableView *table = new QTableView(0);
    table->setModel(model);

    QItemSelectionModel *selectionModel = table->selectionModel();

表视图的默认选择模型会被检索出来以备以后使用。我们不修改模型中的任何项,而是选择一些将显示在表格左上角的项。为此,我们需要获取与待选择区域的左上角和右下角元素对应的模型索引:

    QModelIndex topLeft;
    QModelIndex bottomRight;

    topLeft = model->index(0, 0, QModelIndex());
    bottomRight = model->index(5, 2, QModelIndex());

要在模型中选择这些项,并在tableview中查看相应的更改,需要构建一个selection对象,然后将其应用到selection模型中:

    QItemSelection selection(topLeft, bottomRight);
    selectionModel->select(selection, QItemSelectionModel::Select);

使用由选择标志组合定义的命令,将选择应用于选择模型。在这种情况下,使用的标志会导致记录在selection对象中的项被包含在选择模型中,而不管它们之前的状态如何。结果选择显示在视图中。

通过选择标志定义的各种操作,可以修改对元素项的选择。这些操作产生的选择可能具有复杂的结构,但选择模型有效地表示了这些选择。在学习如何更新选区时,我们会介绍如何使用不同的选择标志来操作所选元素。

读取选区状态

可以使用selectedindex()函数读取存储在selection模型中的模型索引。这将返回一个未排序的模型索引列表,只要我们知道它们用于哪个模型,就可以对其进行迭代:

    const QModelIndexList indexes = selectionModel->selectedIndexes();

    for (const QModelIndex &index : indexes) {
        QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
        model->setData(index, text);
    }

上面的代码使用基于范围的for循环来迭代和修改选择模型返回的索引对应的项。

选择模型发出信号来指示选择中的变化。它们通知其他组件关于整个选择和item模型中当前聚焦项的更改。我们可以将selectionChanged()信号连接到一个插槽,并在选择发生变化时检查模型中被选中或取消选中的项目。插槽用两个QItemSelection对象调用:一个包含一个索引列表,对应于新选择的项;另一个包含对应于新取消选择项的索引。

在下面的代码中,我们提供了一个槽,它接收selectionChanged()信号,用一个字符串填充选定的项目,并清除取消选择的项目的内容。

void MainWindow::updateSelection(const QItemSelection &selected,
    const QItemSelection &deselected)
{
    QModelIndexList items = selected.indexes();

    for (const QModelIndex &index : qAsConst(items)) {
        QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
        model->setData(index, text);
    }

    items = deselected.indexes();

    for (const QModelIndex &index : qAsConst(items)) {
        model->setData(index, QString());
}

我们可以通过将currentChanged()信号连接到一个插槽来跟踪当前聚焦的元素,该插槽通过两个模型索引调用。它们分别对应于前一个获得焦点的项和当前获得焦点的项。

在下面的代码中,我们提供了一个槽,它接收currentChanged()信号,并使用提供的信息更新QMainWindow的状态栏:

void MainWindow::changeCurrent(const QModelIndex &current,
    const QModelIndex &previous)
{
    statusBar()->showMessage(
        tr("Moved from (%1,%2) to (%3,%4)")
            .arg(previous.row()).arg(previous.column())
            .arg(current.row()).arg(current.column()));
}

通过这些信号可以直接监控用户所做的选择,但我们也可以直接更新选择模型。

更新选区

选择命令由选择标志的组合提供,由QItemSelectionModel::SelectionFlag定义。每个选择标志都告诉选择模型,当调用任何一个select()函数时,如何更新选中项的内部记录。最常用的标志是Select标志,它指示选择模型将指定的项记录为已选择。切换标志使选择模型反转指定项的状态,即选择给定的任何未选择项,以及取消选择任何当前选中的项。Deselect标志用来取消选择所有指定的项目。

选择模型中的单个项目是通过创建一个项目选择并将其应用于选择模型来更新的。在下面的代码中,我们将第二次选择项应用到上面显示的表模型,使用Toggle命令翻转给定项的选择状态。

    QItemSelection toggleSelection;

    topLeft = model->index(2, 1, QModelIndex());
    bottomRight = model->index(7, 3, QModelIndex());
    toggleSelection.select(topLeft, bottomRight);

    selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);

操作的结果显示在table view中,提供了一种方便的可视化方式:

默认情况下,选择命令只对模型索引指定的单个项进行操作。但是,用于描述选择命令的标志可以与其他标志结合使用,以改变整个行和列。例如,如果调用select()时只有一个索引,但使用的命令是select和Rows的组合,那么包含引用的项的整行都会被选中。下列代码演示了如何使用Rows和Columns标志:

    QItemSelection columnSelection;

    topLeft = model->index(0, 1, QModelIndex());
    bottomRight = model->index(0, 2, QModelIndex());

    columnSelection.select(topLeft, bottomRight);

    selectionModel->select(columnSelection,
        QItemSelectionModel::Select | QItemSelectionModel::Columns);

    QItemSelection rowSelection;

    topLeft = model->index(0, 0, QModelIndex());
    bottomRight = model->index(1, 0, QModelIndex());

    rowSelection.select(topLeft, bottomRight);

    selectionModel->select(rowSelection,
        QItemSelectionModel::Select | QItemSelectionModel::Rows);

虽然只向选择模型提供了4个索引,但使用行和列选择标志意味着选择了两列和两行。下图显示了这两种选择的结果:

在示例模型上执行的命令都涉及对模型中选择的项目进行累积。也可以清除选区,或者用一个新的选区替换当前选区。

要将当前选区替换为新的选区,需要将其他选区标志与当前标志合并。使用此标志的命令指示选择模型用调用select()时指定的索引替换当前的模型索引集合。要在开始添加新选择之前清除所有选择,请将其他选择标志与clear标志结合起来。这具有重置选择模型的模型索引集合的效果。

选择模型中的所有项

为了选择模型中的所有项,需要为模型的每一层创建一个覆盖该层中所有项的选择。为此,可以使用给定的父索引检索左上角和右下角元素对应的索引:

    QModelIndex topLeft = model->index(0, 0, parent);
    QModelIndex bottomRight = model->index(model->rowCount(parent)-1,
        model->columnCount(parent)-1, parent);

利用这些指标和模型进行选择。然后在selection模型中选择相应的项:

    QItemSelection selection(topLeft, bottomRight);
    selectionModel->select(selection, QItemSelectionModel::Select);

这需要对模型中的所有级别执行。对于顶级元素,我们将按照通常的方式定义父索引:

QModelIndex parent = QModelIndex();

对于分层模型,hasChildren()函数用于确定任何给定项是否为另一层项的父项。

Model/View Programming | Qt Widgets 5.15.17

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

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

相关文章

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询 笛卡尔积的理解和错误笛卡尔积的理解定义例子在数据库中的应用总结 笛卡尔积的错误 正确的多表查询使用 INNER JOIN使用 WHERE 子句&#xff08;隐式内连接&#xff09; 总结 在数据库查询中&#xff0c;特别是涉及到多表…

【python计算机视觉编程——9.图像分割】

python计算机视觉编程——9.图像分割 9.图像分割9.1 图割安装Graphviz下一步&#xff1a;正文9.1.1 从图像创建图9.1.2 用户交互式分割 9.2 利用聚类进行分割9.3 变分法 9.图像分割 9.1 图割 可以选择不装Graphviz&#xff0c;因为原本觉得是要用&#xff0c;后面发现好像用不…

大模型教程:使用 Milvus、vLLM 和 Llama 3.1 搭建 RAG 应用

vLLM 是一个简单易用的 LLM 推理服务库。加州大学伯克利分校于 2024 年 7 月将 vLLM 作为孵化项目正式捐赠给 LF AI & Data Foundation 基金会。欢迎 vLLM 加入 LF AI & Data 大家庭&#xff01;&#x1f389; 在主流的 AI 应用架构中&#xff0c;大语言模型&#xff…

数据清洗-缺失值处理-缺失值可视化图(竖线)

目录 一、安装所需的python包二、缺失值可视化分析2.1 可直接运行代码2.2 以某个缺失值数据进行可视化实战2.2.1 代码运行过程截屏&#xff1a;2.2.2 缺失图可视化&#xff1a; 感觉大家对原理性的东西不太感兴趣&#xff0c;那我就直接举例提供代码&#xff0c;以及详细的注释…

13、Python如何设置文件缓冲

什么是I/O操作&#xff0c;看一下百度百科的说法&#xff1a;I/O操作是指对设备与cpu连接的接口电路的操作&#xff0c;不是对外围设备直接进行操作。宏观上讲&#xff0c;I/O是信息处理系统&#xff08;例如计算机&#xff09;与外部世界&#xff08;可能是人或其他信息处理系…

Flutter之SystemChrome全局设置

一、简介 SystemChrome作为一个全局属性&#xff0c;很像 Android 的 Application&#xff0c;功能很强大。 二、使用详解 2.1 setPreferredOrientations 设置屏幕方向 在我们日常应用中可能会需要设置横竖屏或锁定单方向屏幕等不同要求&#xff0c;通过 setPreferredOrien…

阿里云镜像报错 [Errno 14] HTTP Error 302 - Found 问题解决记录

1、问题背景和解决思路 在本地安装 CentOS7 后&#xff0c;网络已调通可正常上网&#xff0c;但切换阿里云镜像后&#xff0c;使用 yum 安装软件时出现 “[Errno 14] HTTPS Error 302 - Found Trying other mirror.” 报错&#xff0c;原因是 yum 源配置问题。给出了详细的解决…

分布式可信认证:数据安全与隐私保护新范式

文章目录 前言一、可信数字身份成数据要素流通的关键二、分布式可信认证成数据安全与隐私保护新范式1、分布式可信认证很好地解决传统数字身份认证的痛点问题2、可信数字身份上升为国家战略三、安全是未来数字身份的基础1、有效的威胁建模策略是确保这些系统安全性的基石前言 …

数据清洗-缺失值填充-随机森林搜寻最优参数填充

目录 一、安装所需的python包二、采用随机森林算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战代码运行过程截屏&#xff1a;填充后的数据截屏&#xff1a; 三、随机森林算法 (Random Forest) 介绍3.1随机森林的定义3.2随机森林的基本思想3.3随机森林的工作原…

语言模型中的多模态链式推理(论文复现)

语言模型中的多模态链式推理&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 语言模型中的多模态链式推理&#xff08;论文复现&#xff09;简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模…

redis短信登录模型

基于Session实现登录 &#xff0c;

Unity程序基础框架

概述 单例模式基类 没有继承 MonoBehaviour 继承了 MonoBehaviour 的两种单例模式的写法 缓存池模块 &#xff08;确实挺有用&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine;/// <summary> /// 缓存池模块 /// 知识点 //…

数据结构基础详解:哈希表【C语言代码实践篇】开放地址法__拉链法_哈希表的创建_增删查操作详解

文章目录 1.哈希表代码实现之开放地址法1.1 开放地址法创建哈希表1.2 开放地址法之查找1.3 开放地址法之插入1.4 开放地址法之删除 2.哈希表代码实现之链地址法(拉链法)2.1 链地址法之创建哈希表2.2 链地址法之查找2.3 链地址法之插入2.4 链地址法之删除 1.哈希表代码实现之开放…

Stable diffusion生图原理

简介 Stable diffusion 是一种基于扩散技术的深度学习模型&#xff0c;于2022年发布&#xff0c;是Stability AI公司推出的首要产品&#xff0c;它主要用于生成以文本描述为条件的详细图像&#xff0c;同时也可以进行补绘、外绘、重绘等任务&#xff0c;但原理都和文生图原理…

C++中矩阵的介绍及相关应用扩展详解

1. 矩阵概念 在数学中&#xff0c;矩阵&#xff08;Matrix&#xff09;是一个按照长方阵列排列的复数或实数集合&#xff0c;最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。 矩阵是高等代数学中的常见工具&#xff0c;也常见于统计分析…

Qt-QPushButton按钮类控件(22)

目录 描述 使用 给按钮添加图片 给按钮添加快捷键 添加槽函数 添加快捷键 添加组合键 开启鼠标的连发功能 描述 经过上面的一些介绍&#xff0c;我们也尝试的使用过了这个控件&#xff0c;接下来我们就要详细介绍这些比较重要的控件了 使用 给按钮添加图片 我们创建…

线性表之单链表

在上一节我们学习了线性表中的顺序表&#xff0c;今天我们来学习一下线性表中的另一种结构——单链表 前言 我们在之前已经初步了解了数据结构中的两种逻辑结构&#xff0c;但线性结构中并非只有顺序表一种&#xff0c;它还有不少兄弟姐妹&#xff0c;今天我们再来学习一下单链…

RealityCapture全面讲解:摄影测量软件的新纪元

随着数字化技术的迅猛发展&#xff0c;摄影测量软件在各行各业中的应用日益广泛。其中&#xff0c;RealityCapture作为一款领先的摄影测量解决方案&#xff0c;以其卓越的速度、精度和易用性&#xff0c;赢得了全球众多专业人士的青睐。本文将全面讲解RealityCapture的功能特点…

演示:基于WPF自绘的中国省份、城市、区县矢量地图

一、目的&#xff1a;演示一个基于WPF自绘的中国省份、城市、区县矢量地图 二、效果 国 省 市 三、功能 支持实际经纬度显示 支持平移&#xff0c;缩放等功能 显示中国地图 显示各个省份地图 显示各个省份地图&#xff08;包含在表格中&#xff0c;包含缩率图&#xff09; 显…

UE4_后期处理五—饱和度调整、隔离、扭曲、重影

一、色彩饱和度调整&#xff1a; 原图 后期处理材质节点&#xff1a; 效果图&#xff1a; 可以根据参数saturation调整饱和还是去饱和。 当saturation为1时&#xff1a;去饱和度&#xff0c;如下图&#xff1a; 当saturation为0时&#xff1a;原始的一个状态&#xff0c;如下…