界面开发框架Qt新手入门 - 自定义排序/筛选模型示例(二)

news2024/11/22 20:02:02

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

自定义排序/筛选模型示例说明了如何子类化QSortFilterProxyModel来执行高级排序和筛选。

在上文中(点击这里回顾>>),为大家讲解了如何实现MySortFilterProxyModel类、MySortFilterProxyModel的定义,本文将继续讲解Window类的定义和实现!

点击获取Qt Widget组件下载

Window类定义

CustomFilter类继承了QWidget,并提供了这个例子的主应用程序窗口:

class Window : public QWidget
{
Q_OBJECT

public:
Window();

void setSourceModel(QAbstractItemModel *model);

private slots:
void textFilterChanged();
void dateFilterChanged();

private:
MySortFilterProxyModel *proxyModel;

QGroupBox *sourceGroupBox;
QGroupBox *proxyGroupBox;
QTreeView *sourceView;
QTreeView *proxyView;
QLabel *filterPatternLabel;
QLabel *fromLabel;
QLabel *toLabel;
FilterWidget *filterWidget;
QDateEdit *fromDateEdit;
QDateEdit *toDateEdit;
};

我们实现了两个私有槽,textFilterChanged()和dateFilterChanged(),用于响应用户更改过滤器模式、区分大小写或任何日期,此外还实现了一个公共的setSourceModel()方便函数来设置模型/视图关系。

Window类实现

在本示例中,我们选择在main()函数中创建和设置源模型,因此在构建主应用程序窗口时,假设源模型已经存在,并从创建自定义代理模型的实例开始:

Window::Window()
{
proxyModel = new MySortFilterProxyModel(this);

我们设置dynamicSortFilter属性,该属性保存代理模型是否被动态排序和过滤。通过将该属性设置为true,可以确保在源模型的内容发生变化时对模型进行排序和过滤。

主应用程序窗口显示源模型和代理模型的视图,源视图非常简单:

sourceView = new QTreeView;
sourceView->setRootIsDecorated(false);
sourceView->setAlternatingRowColors(true);

QTreeView类提供了树视图的默认模型/视图实现,视图实现了应用程序源模型中项目的树表示。

sourceLayout->addWidget(sourceView);
sourceGroupBox = new QGroupBox(tr("Original Model"));
sourceGroupBox->setLayout(sourceLayout);

QTreeView 类提供了树视图的默认模型/视图实现,视图实现了应用程序源模型中项目的树表示,将视图小部件添加到我们安装在相应组框上的布局中。

另一方面代理模型视图包含几个控件,这些控件控制转换源模型数据结构的各个方面:

filterWidget = new FilterWidget;
filterWidget->setText(tr("Grace|Sports"));
connect(filterWidget, &FilterWidget::filterChanged, this, &Window::textFilterChanged);

filterPatternLabel = new QLabel(tr("&Filter pattern:"));
filterPatternLabel->setBuddy(filterWidget);

fromDateEdit = new QDateEdit;
fromDateEdit->setDate(QDate(1970, 01, 01));
fromLabel = new QLabel(tr("F&rom:"));
fromLabel->setBuddy(fromDateEdit);

toDateEdit = new QDateEdit;
toDateEdit->setDate(QDate(2099, 12, 31));
toLabel = new QLabel(tr("&To:"));
toLabel->setBuddy(toDateEdit);

connect(filterWidget, &QLineEdit::textChanged,
this, &Window::textFilterChanged);
connect(fromDateEdit, &QDateTimeEdit::dateChanged,
this, &Window::dateFilterChanged);
connect(toDateEdit, &QDateTimeEdit::dateChanged,
this, &Window::dateFilterChanged);

请注意,每当用户更改其中一个过滤选项时,我们必须显式地重新应用该过滤器,这是通过将各种编辑器连接到更新代理模型的函数来完成的。

proxyView = new QTreeView;
proxyView->setRootIsDecorated(false);
proxyView->setAlternatingRowColors(true);
proxyView->setModel(proxyModel);
proxyView->setSortingEnabled(true);
proxyView->sortByColumn(1, Qt::AscendingOrder);

QGridLayout *proxyLayout = new QGridLayout;
proxyLayout->addWidget(proxyView, 0, 0, 1, 3);
proxyLayout->addWidget(filterPatternLabel, 1, 0);
proxyLayout->addWidget(filterWidget, 1, 1);
proxyLayout->addWidget(fromLabel, 3, 0);
proxyLayout->addWidget(fromDateEdit, 3, 1, 1, 2);
proxyLayout->addWidget(toLabel, 4, 0);
proxyLayout->addWidget(toDateEdit, 4, 1, 1, 2);

proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model"));
proxyGroupBox->setLayout(proxyLayout);

排序将由视图处理,我们所要做的就是通过设置QTreeView::sortingEnabled属性(默认为false)来启用代理视图的排序。然后,我们将所有过滤小部件和代理视图添加到安装在相应组框上的布局中。

QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(sourceGroupBox);
mainLayout->addWidget(proxyGroupBox);
setLayout(mainLayout);

setWindowTitle(tr("Custom Sort/Filter Model"));
resize(500, 450);
}

最后,在将两个组框放入安装在主应用程序小部件上的另一个布局中之后,自定义应用程序窗口。

如上所述,在main()函数中创建源模型,调用Window::setSourceModel()函数使应用程序使用它:

void Window::setSourceModel(QAbstractItemModel *model)
{
proxyModel->setSourceModel(model);
sourceView->setModel(model);

for (int i = 0; i < proxyModel->columnCount(); ++i)
proxyView->resizeColumnToContents(i);
for (int i = 0; i < model->columnCount(); ++i)
sourceView->resizeColumnToContents(i);
}

QSortFilterProxyModel::setSourceModel()函数使代理模型处理给定模型中的数据,在本例中是邮件模型,视图小部件从QAbstractItemModel 类继承的setModel() 为视图设置要呈现的模型。注意,后一个函数还将创建和设置一个新的选择模型。

void Window::textFilterChanged()
{
FilterWidget::PatternSyntax s = filterWidget->patternSyntax();
QString pattern = filterWidget->text();
switch (s) {
case FilterWidget::Wildcard:
pattern = QRegularExpression::wildcardToRegularExpression(pattern);
break;
case FilterWidget::FixedString:
pattern = QRegularExpression::escape(pattern);
break;
default:
break;
}

QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
if (filterWidget->caseSensitivity() == Qt::CaseInsensitive)
options |= QRegularExpression::CaseInsensitiveOption;
QRegularExpression regularExpression(pattern, options);
proxyModel->setFilterRegularExpression(regularExpression);
}

每当用户更改过滤器模式或区分大小写时,就调用textFilterChanged()函数。

首先检索首选语法(FilterWidget::PatternSyntax enum用于解释给定模式的含义),然后确定首选的大小写敏感性。基于这些参数和当前的过滤器模式,我们设置代理模型的filterRegularExpression 属性。filterRegularExpression 属性保存用于过滤源模型内容的正则表达式,注意调用QSortFilterProxyModel的setfilterregulareexpression()函数也会更新模型。

void Window::dateFilterChanged()
{
proxyModel->setFilterMinimumDate(fromDateEdit->date());
proxyModel->setFilterMaximumDate(toDateEdit->date());
}

每当用户修改有效日期范围时,就调用dateFilterChanged()函数,从用户界面检索新的日期,并调用相应的函数(由自定义代理模型提供)来设置代理模型的最小和最大日期。如上所述,调用这些函数也会更新模型。

Main()函数

在本例中我们通过在main()函数中创建模型,将应用程序与源模型分离开来。首先我们创建应用程序,然后创建源模型:

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.setSourceModel(createMailModel(&window));
window.show();
return app.exec();
}

createMailModel()函数是为简化构造函数而提供的方便函数,它所做的就是创建并返回一个描述电子邮件集合的模型。该模型是QStandardItemModel类的一个实例,也就是说,一个用于存储自定义数据的通用模型,通常用作标准Qt数据类型的存储库,每个邮件描述都使用addMail()(另一个方便的函数)添加到模型中。

 

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

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

相关文章

ALOHA 开源机械臂(Viper 300 Widow X 250 6DOF机械臂组成)第一部分

软件简介&#xff1a; ALOHA 即 A Low-cost Open-source Hardware System for Bimanual Teleoperation&#xff0c;是一个低成本的开源双手遥控操作硬件系统&#xff0c;即开源机械臂。其算法 Action Chunking with Transformers (ACT) 采用了神经网络模型 Transformers&#…

#杂谈 个人嵌入式开发的学习

本人目前从事的是嵌入式软件开发的相关工作。这是一个关于个人做项目时用过的开发工具的杂谈&#xff0c;仅是为了记录学习经历&#xff0c;同时也为和我有同样瞎搞东西的爱好者提供一个学习思路。 前言 我的技术栈&#xff1a; 下面介绍一下我用过在或者还在用的开发工具&…

JavaWeb综合案例-Servlet优化

将WebServlet的访问路径不要写死&#xff0c;写成通配符的形式 1. 反射笔记&#xff08;后续代码会用到该机制&#xff09; 1.1 基础概念 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&am…

【Nodejs】Express实现接口

介绍 Express 是一个第三方模块&#xff0c;用于快速搭建服务器 类似于jquery与DOMExpress 是一个基于 Node.js 平台&#xff0c;快速、开放、极简的 web 开发框架。express保留了http模块的基本API&#xff0c;使用express的时候&#xff0c;也能使用http的APIexpress还额外封…

【花雕学AI】我们如何才能避免被ChatGPT替代?——一个跨学科的视角

ChatGPT是一个由OpenAI开发的AI文本工具&#xff0c;它可以理解和生成自然语言&#xff0c;从而与用户进行对话。ChatGPT是基于GPT-3或者GPT-4模型的&#xff0c;这是目前最大和最先进的语言模型之一。ChatGPT通过在大量的互联网文本数据上进行预训练和强化学习&#xff0c;学习…

linux修改程序的配置文件

修改指定文件中的数&#xff0c;例如创建一个文件如图 把6修改成7 修改完成 代码如下&#xff1a; #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #incl…

【英语】大学英语CET考试,阅读部分1(阅读概述,SectionC仔细阅读140)

文章目录 1、阅读概述1.1 考试概况&#xff1a;大纲解读备考策略1.2 做题原则&#xff1a;定位1.3 标点符号和句子逻辑1.4 一级词汇 2、细节题&#xff08;10题占9题&#xff09;2.1 逻辑关系&#xff08;并列和递进&#xff0c;同一方向&#xff09;2.2 逻辑关系&#xff08;转…

Flutter学习之旅 -AspectRatio Card CircleAvatar组件

文章目录 AspectRatioCardCircleAvatar定义方法封装 AspectRatio AspectRatio的作用是根据设置调整子元素child的宽高比。 class MyHomePage extends StatelessWidget {const MyHomePage({Key? key}) : super(key: key);overrideWidget build(BuildContext context) {//获取设…

解决文件夹显示“文件夹变文件”的方法

在文件夹属性设置中&#xff0c;找到“文件名”&#xff0c;双击一下&#xff0c;选中的项目就会显示为“文件夹”&#xff0c;如果没有选中&#xff0c;点击“打开文件夹”就可以了。这是因为系统在默认情况下&#xff0c;所有的文件夹都是以系统默认的路径来命名的。当然也有…

构建 Kubernetes Operator 的原则是什么?

Kubernetes&#xff08;简称K8s&#xff09;上数据服务的自动化越来越受欢迎。在K8s上运行有状态的工作负载意味着使用Operator。然而&#xff0c;它发展演化到今天已经变得非常复杂&#xff0c;像Operator这样的应用模式和扩展方式对于开发者与运维者而言愈发受到欢迎。 但工…

【勝讯云 Finops Crane 集训营】基于 FinOps 的云资源分析与成本优化平台实操及说明

介绍 Crane 是由腾讯云主导开源的国内第一个基于云原生技术的成本优化项目&#xff0c;遵循 FinOps 标准&#xff0c;已经获得FinOps基金会授予的全球首个认证降本增效开源方案。它为使用 Kubernetes 集群的企业提供了一种简单、可靠且强大的自动化部署工具。 Crane 的设计初衷…

来这公司一年碰到的问题比我过去10年都多

无意间发现我们 Kafka 管理平台的服务的 open files 和 CPU 监控异常&#xff0c;如下图&#xff0c;有一台机器 CPU 和 opfen files 指标持续在高位&#xff0c;尤其是 open files 达到了4w。 原因分析 第一反应是这个服务请求很高&#xff1f;但是这个服务是一个管理服务不应…

云安全的挑战与发展:云原生安全将是未来趋势吗?

引言 随着企业数字化转型的推进和云计算的普及&#xff0c;云安全已经成为了当下IT行业的热点话题之一。尽管云计算已经被广泛应用&#xff0c;但在云安全方面仍存在一些挑战和问题。本文将探讨当前云安全面临的挑战&#xff0c;并分析云原生安全在未来的发展趋势。 第一章 云…

Opera One将取代 Opera 浏览器

导读Opera 日前推出了一款名为 Opera One 的新浏览器&#xff0c;该浏览器正处于开发者预览阶段&#xff0c;用户可以访问官网下载试用&#xff08;链接&#xff09;。这个浏览器的终极目标是在今年晚些时候取代其当家的 Opera 浏览器。 Opera One 遵循 "模块化设计理念&q…

Netty(2)

Netty 文章目录 Netty4 Netty 模型4.1 Netty 模型介绍4.2 Netty demo4.3 Netty 异步模型4.3.1 基本介绍4.3.2 异步模型4.3.3 Future-Listener 机制4.4 Netty 任务队列 task 4 Netty 模型 4.1 Netty 模型介绍 Netty 线程模式&#xff1a;Netty 主要基于主从 Reactor 多线程模型…

2023年开源社项目委员会介绍

2023 项目委员会成员 项目委员会主席&#xff1a;石垚 &#xff08;tech-querykaiyuanshe.org&#xff09; 项目委员会秘书 &#xff1a;丁文昊 &#xff08;dingwenhaokaiyuanshe.org&#xff09; 开源社官网项目组&#xff1a; 组长&#xff1a;石垚 &#xff08;tech-queryk…

2023 ATTCK v13版本更新指南

一、什么是ATT&CK ATT&CK&#xff08;Adversarial Tactics, Techniques, and Common Knowledge &#xff09;是一个攻击行为知识库和模型&#xff0c;主要应用于评估攻防能力覆盖、APT情报分析、威胁狩猎及攻击模拟等领域。 二、ATT&CK 发展历史 1996年&#xff1…

【UE】高级载具插件-04-坦克瞄准开火

在上一篇文章中&#xff08;【UE】高级载具插件-03-子弹击中目标时使目标破碎&#xff09;&#xff0c;我们实现了坦克开火的功能。本篇博客介绍的是实现坦克瞄准开火的功能。 效果 步骤 1. 首先将学习FPS游戏时用到的动态准心控件蓝图资源导入 2. 在项目设置中增加两个操作…

穿越有序链表的迷宫:探索力扣“合并两个有序链表”的解题思路

本篇博客计划讲解力扣“21. 合并两个有序链表”这道题&#xff0c;这是题目链接。 老规矩&#xff0c;先来审下题干。 输出示例如下&#xff1a; 提示&#xff1a; 这道题目相当经典&#xff0c;同时是校招的常客。大家先思考一下&#xff0c;再来听我讲解。 思路&…

7.1 幂法和反幂法

学习目标&#xff1a; 如果我要学习幂法及反幂法&#xff0c;我会遵循以下步骤&#xff1a; 1. 学习理论知识&#xff1a;首先我会找到可靠的教材或者网上资源&#xff0c;学习幂法及反幂法的理论知识&#xff0c;包括其原理、公式、算法流程、收敛性等方面的内容。这些知识可…