界面开发框架Qt新手入门指南 - 使用Calendar组件创建日历(一)

news2024/12/23 17:47:42

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

本文中的CalendarWidget示例展示了QCalendarWidget的用法。

点击获取Qt Widget组件下载

QCalendarWidget一次显示一个日历月,并允许用户选择一个日期。日历由四个组件组成:一个允许用户更改显示月份的导航栏、一个网格,其中每个单元格表示一个月中的一天,以及两个显示星期名称和星期数字的标题。

Calendar Widget示例显示一个QCalendarWidget,并允许用户使用QComboBoxes、QCheckBoxes和QDateEdits配置其外观和操作,此外,用户可以影响单个日期和标题的格式。

QCalendarWidget的属性总结如下:

  • selectedDate:当前选择的日期。
  • minimumDate:可以选择的最早日期。
  • maximumDate:可以选择的最晚日期。
  • firstDayOfWeek:显示为一周的第一天的日期(通常是星期日或星期一)。
  • gridVisible:是否显示网格。
  • selectionMode:用户是否可以选择日期。
  • horizontalHeaderFormat:水平标题中日期名称的格式(例如,"M", "Mon"或"Monday")。
  • verticalHeaderFormat:垂直页眉的格式。
  • navigationBarVisible:是否显示日历小部件顶部的导航栏。

本示例包含一个类Window,它创建并布局QCalendarWidget和其他让用户配置QCalendarWidget的小部件。

窗口类定义

下面是Window类的定义:

class Window : public QWidget
{
Q_OBJECT

public:
Window(QWidget *parent = nullptr);

private slots:
void localeChanged(int index);
void firstDayChanged(int index);
void selectionModeChanged(int index);
void horizontalHeaderChanged(int index);
void verticalHeaderChanged(int index);
void selectedDateChanged();
void minimumDateChanged(QDate date);
void maximumDateChanged(QDate date);
void weekdayFormatChanged();
void weekendFormatChanged();
void reformatHeaders();
void reformatCalendarPage();

private:
void createPreviewGroupBox();
void createGeneralOptionsGroupBox();
void createDatesGroupBox();
void createTextFormatsGroupBox();
QComboBox *createColorComboBox();

QGroupBox *previewGroupBox;
QGridLayout *previewLayout;
QCalendarWidget *calendar;

QGroupBox *generalOptionsGroupBox;
QLabel *localeLabel;
QLabel *firstDayLabel;
...
QCheckBox *mayFirstCheckBox;
};

与表示自包含窗口的类一样,大多数API都是私有的。当我们在执行过程中偶然发现私人成员时,将对其进行审查。

窗口类实现

现在让我们回顾一下类的实现,从构造函数开始:

Window::Window(QWidget *parent)
: QWidget(parent)
{
createPreviewGroupBox();
createGeneralOptionsGroupBox();
createDatesGroupBox();
createTextFormatsGroupBox();

QGridLayout *layout = new QGridLayout;
layout->addWidget(previewGroupBox, 0, 0);
layout->addWidget(generalOptionsGroupBox, 0, 1);
layout->addWidget(datesGroupBox, 1, 0);
layout->addWidget(textFormatsGroupBox, 1, 1);
layout->setSizeConstraint(QLayout::SetFixedSize);
setLayout(layout);

previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());

setWindowTitle(tr("Calendar Widget"));
}

我们首先使用四个私有的create…GroupBox()函数创建四个qgroupbox及其子部件(包括QCalendarWidget),如下所述,然后在QGridLayout中安排组框。

我们将网格布局的调整大小策略设置为QLayout::SetFixedSize,以防止用户调整窗口大小。在这种模式下,窗口的大小由QGridLayout根据其内容小部件的大小提示自动设置。

为了确保在每次更改QCalendarWidget的属性(例如,隐藏导航栏、垂直标题或网格)时不会自动调整窗口的大小,我们将第0行的最小高度和第0列的最小宽度设置为QCalendarWidget的初始大小。

让我们来看看createPreviewGroupBox()函数:

void Window::createPreviewGroupBox()
{
previewGroupBox = new QGroupBox(tr("Preview"));

calendar = new QCalendarWidget;
calendar->setMinimumDate(QDate(1900, 1, 1));
calendar->setMaximumDate(QDate(3000, 1, 1));
calendar->setGridVisible(true);

connect(calendar, &QCalendarWidget::currentPageChanged,
this, &Window::reformatCalendarPage);

previewLayout = new QGridLayout;
previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
previewGroupBox->setLayout(previewLayout);
}

Preview组框只包含一个小部件:QCalendarWidget,我们设置它,将它的currentPageChanged()信号连接到reformatCalendarPage()插槽,以确保每个新页面都获得用户指定的格式。

createGeneralOptionsGroupBox()函数有点大,并且以相同的方式设置了几个小部件。我们将在这里查看它的部分实现,并跳过其余部分:

void Window::createGeneralOptionsGroupBox()
{
generalOptionsGroupBox = new QGroupBox(tr("General Options"));

localeCombo = new QComboBox;
int curLocaleIndex = -1;
int index = 0;
for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
QLocale::Language lang = static_cast<QLocale::Language>(_lang);
const auto locales =
QLocale::matchingLocales(lang, QLocale::AnyScript, QLocale::AnyTerritory);
for (auto loc : locales) {
QString label = QLocale::languageToString(lang);
auto territory = loc.territory();
label += QLatin1Char('/');
label += QLocale::territoryToString(territory);
if (locale().language() == lang && locale().territory() == territory)
curLocaleIndex = index;
localeCombo->addItem(label, loc);
++index;
}
}
if (curLocaleIndex != -1)
localeCombo->setCurrentIndex(curLocaleIndex);
localeLabel = new QLabel(tr("&Locale"));
localeLabel->setBuddy(localeCombo);

firstDayCombo = new QComboBox;
firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
firstDayCombo->addItem(tr("Monday"), Qt::Monday);
firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
firstDayCombo->addItem(tr("Friday"), Qt::Friday);
firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);

firstDayLabel = new QLabel(tr("Wee&k starts on:"));
firstDayLabel->setBuddy(firstDayCombo);
...

我们从组合框上的周开始设置开始,此组合框控制哪一天应显示为一周的第一天。

QComboBox类允许我们将用户数据作为QVariant附加到每个项目,稍后可以使用QComboBox的itemData()函数检索数据。QVariant不直接支持Qt::DayOfWeek数据类型,但它支持int, c++会很乐意将任何enum值转换为int。

...
connect(localeCombo, &QComboBox::currentIndexChanged,
this, &Window::localeChanged);
connect(firstDayCombo, &QComboBox::currentIndexChanged,
this, &Window::firstDayChanged);
connect(selectionModeCombo, &QComboBox::currentIndexChanged,
this, &Window::selectionModeChanged);
connect(gridCheckBox, &QCheckBox::toggled,
calendar, &QCalendarWidget::setGridVisible);
connect(navigationCheckBox, &QCheckBox::toggled,
calendar, &QCalendarWidget::setNavigationBarVisible);
connect(horizontalHeaderCombo, &QComboBox::currentIndexChanged,
this, &Window::horizontalHeaderChanged);
connect(verticalHeaderCombo, &QComboBox::currentIndexChanged,
this, &Window::verticalHeaderChanged);
...

在创建了小部件之后,我们连接信号和插槽,将组合框连接到Window的私有槽或QComboBox提供的公共槽。

...
firstDayChanged(firstDayCombo->currentIndex());
selectionModeChanged(selectionModeCombo->currentIndex());
horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
verticalHeaderChanged(verticalHeaderCombo->currentIndex());
}

在函数的最后,我们调用更新日历的槽,以确保QCalendarWidget在启动时与其他小部件同步。

在下文中,我们将继续介绍更多实现窗口类的函数,欢迎持续关注哦~

 

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

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

相关文章

docker ansible与剧本模式

ansible&#xff08;跨主机编排&#xff09; ansible 是一个基于python开发的配置管理和应用部署和管理工具&#xff0c;现在也在自动化管理领域大放异彩&#xff0c;他融合了众多老牌运维工具的优点&#xff0c;pubbet和saltstack能实现的功能&#xff0c;ansible基本上都可以…

antd-vue - - - - - table增加统计行?

table增加统计行 尝试一、footer & Summary使用summary尝试二、直接将统计行push进dataSource 第一次遇到这个需求&#xff0c;有点懵。 在【antd-v table】官网仔细看了一番&#xff0c;找到这么两个配置footer[表格尾部]和Summary[总结栏]  所以可以证明&#xff0c;你所…

TDEngine3.x数据查询及插入调优

一、数据库创建 vgroups 配置 如果不了解vgroup概念&#xff0c;建议到官网查看&#xff1a;TDEngine官网-数据模型和整体架构 从服务端配置的角度&#xff0c;要根据系统中磁盘的数量&#xff0c;磁盘的 I/O 能力&#xff0c;以及处理器能力在创建数据库时设置适当的 vgroups…

Qt编写onvif工具(搜索/云台/预置位/OSD/录像存储)

一、前言 从最初编写这个工具开始的时间算起来&#xff0c;至少5年多&#xff0c;一直持续完善到今天&#xff0c;这个工具看起来小也不小大也不大&#xff0c;但是也是经历过无数个现场的洗礼&#xff0c;毫不夸张的说&#xff0c;市面上能够遇到的主流的厂商的设备&#xff…

【Flutter】如何 Dialog 弹窗设置点击空白处不关闭

文章目录 一、 引言二、 Flutter 中的 Dialog 弹窗1. 默认的 Dialog 行为介绍2. 解释为什么在某些情况下我们需要点击空白处不关闭 Dialog 三、 如何在 Flutter 中设置 Dialog 弹窗点击空白处不关闭1. 展示简单的代码示例2. 详细解释代码的每个部分 四、 一个完整的 Flutter Di…

SpringCloud服务注册与发现组件Eureka(五)

Eureka github 地址&#xff1a; https://github.com/Netflix/eureka Eureka简介 Eureka是Netflix开发的服务发现框架&#xff0c;本身是一个基于REST的服务&#xff0c;主要用于定位运行在AWS域中的中间层服务&#xff0c;以达到负载均衡和中间层服务故障转移的目的。Spring…

迈入大模型时代,多模态AI通用化成未来趋势,景联文科技提供多模态数据集

ChatGPT带来2023年第一个火爆的风口。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;拥有语言理解和文本生成能力。无论是强大的视频脚本、文案、邮件、翻译、代码等内容生成能力&#xff0c;还是语义推理、情绪分析等对话能力&#xff0c;都让大众眼前一亮&#xf…

C++类和对象(继承)

4.6继承 继承是面向对象三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; 我们发现&#xff0c;定义这些类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性。 这个时候我们就可以考虑利用继承的技术&#xff0c;减…

阿里云PAIx达摩院GraphScope开源基于PyTorch的GPU加速分布式GNN框架

作者&#xff1a;艾宝乐 导读 近期阿里云机器学习平台 PAI 团队和达摩院 GraphScope 团队联合推出了面向 PyTorch 的 GPU 加速分布式 GNN 框架 GraphLearn-for-PyTorch(GLT) 。GLT 利用 GPU 的强大并行计算性能来加速图采样&#xff0c;并利用 UVA 来减少顶点和边特征的转换和…

Spring Security Oauth2.1 最新版 1.1.0 整合 gateway 完成授权认证(拥抱 springboot 3.1)

目录 背景 版本 Spring Boot 3.1 Spring Authorization Server 1.1.0官方文档 基础 spring security OAuth2.0 模块构成 授权方式 集成过程 官方demo 代码集成 依赖 授权服务AuthorizationServerConfig配置 重要组件 测试 查看授权服务配置 访问授权服务 授…

AB32VG1:SDK_AB53XX_V061(5)蓝牙BLE测试笔记

文章目录 1.配置工程&#xff0c;重新编译1.1替换链接库libbtstack_dm.a1.2 《config.h》打开编译开关1.3 在 Downloader 里面打开 BLE 开关 2.ABLink&#xff08;手机APP&#xff09;控制2.1 app下载2.2 安装后打开&#xff0c;搜索蓝牙Bluetrum&#xff1a;2.3 操作存储卡 3.…

深度学习应用篇-元学习[14]:基于优化的元学习-MAML模型、LEO模型、Reptile模型

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

华为认证 | HCIP-Datacom-Core 考试大纲

01 考试概况 02 考试内容 HCIP-Datacom-Core Technology V1.0考试覆盖数据通信领域各场景通用核心知识&#xff0c;包括路由基础、OSPF、 IS-IS、BGP、路由和流量控制、以太网交换技术、组播、IPv6、网络安全、网络可靠性、网络服务与管理、 WLAN、网络解决方案。 ★路由基础 …

【MySQL 函数】:一文彻底搞懂 MySQL 函数(一)

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL字符串函数和数学函数的讲解✨ 目录 前言一、字符串函数二、数学函数三、总结 一、字符串函数 函数作用UPPER(列|字符串)将字符串每个字符转为大写LOWER(列|字符串)将字符串每个字符转为小写CONCAT(str1,str2,…

阿里云企业邮箱购买流程

阿里云企业邮箱购买流程&#xff0c;企业邮箱分为免费版、标准版、集团版和尊享版&#xff0c;阿里云百科分享企业邮箱版本区别&#xff0c;企业邮箱收费标准价格表&#xff0c;以及阿里企业邮箱详细购买流程&#xff1a; 目录 阿里云企业邮箱购买流程 一、阿里云账号注册及…

OpenAI 刚刚宣布了海量更新

OpenAI 刚刚宣布了海量更新&#xff0c;增加函数调用&#xff0c;支持更长上下文&#xff0c;价格更低&#xff01; ​新模型上架 1、gpt-4-0613 2、gpt-4-32k-0613 3、gpt-3.5-turbo-0613 4、gpt-3.5-turbo-16k 部分模型降价 1、text-embedding-ada-002&#xff1a;$0.00…

DevExpress WinForms功能区组件,让业务应用创建更轻松!(上)

DevExpress WinForms的Ribbon&#xff08;功能区&#xff09;组件灵感来自于Microsoft Office&#xff0c;并针对WinForms开发人员进行了优化&#xff0c;它可以帮助开发者轻松地模拟当今最流行的商业生产应用程序。 PS&#xff1a;DevExpress WinForm拥有180组件和UI库&#…

Linux安装SQLServer数据库

Linux安装SQLServer数据库 文章目录 Linux安装SQLServer数据库SQLServer是什么SQLServer的安装安装要求安装步骤安装配置安装命令行工具 SQLServer是什么 美国 Microsoft 公司推出的一种关系型数据库系统。SQL Server 是一个可扩展的、高性能的、为分布式客户机/服务器计算所设…

[PostgreSQL-16新特性之EXPLAIN的GENERIC_PLAN选项]

随着PostgreSQL-16beta1版本的发布&#xff0c;我们可以发现&#xff0c;对于我们时常使用的explain增加了一个GENERIC_PLAN选项。这个选项是允许了包含参数占位符的语句&#xff0c;如select * from tab01 where id$1;等等这种语句&#xff0c;让其生成不依赖于这些参数值的通…

两个HC-05蓝牙之间的配对

两个HC-05蓝牙之间的配对 文章目录 两个HC-05蓝牙之间的配对1.进入AT指令模式后&#xff0c;先确定是否为AT模式&#xff1a;2.获取模块A,B的地址3.将蓝牙A配置为主模式&#xff0c;将蓝牙B配置为从模式&#xff1a;4.设置模块通信波特率,蓝牙模块A和B的配置需要相同6.验证 买了…