08 Qt自绘制日历控件:摆脱丑的让人无语的原生QCalendarWidget

2024-03-01 00:36

本文主要是介绍08 Qt自绘制日历控件:摆脱丑的让人无语的原生QCalendarWidget,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

前言

一、示意图

1.1 Qt原生式样风格:

1.2 Qt自绘制目标效果图:

二、实现思路

2.1 概述

2.2 部分绘制说明

1.绘制日期

2.定制周信息栏

3.定制日历导航栏 

总结


前言

在QtGui中,日历控件是一种非常常用的用户界面元素,用于显示和选择日期。

Qt提供了一个原生的日历控件类QCalendarWidget。但是,原生的日历控件真的丑的让人窒息!那么在这时候,也就需要我们不得不对其外观进行自定义绘制,以满足特定的设计需求。在本文中,我们将介绍如何使用Qt的自定义绘制功能来对原生日历控件进行个性化定制。

一、示意图

1.1 Qt原生式样风格:

原生风格
原生风格

1.2 Qt自绘制目标效果图:

目标效果图

二、实现思路

2.1 概述

日历组件自绘制共可拆解为以下几部分:

 1>日历导航栏

2>日历的周信息

3>日期详情信息

2.2 部分绘制说明

1.绘制日期

为了沿用QCalendarWidget的日历关联功能接口,所以我们要继承QCalendarWidget。
在这个类中,我们将重写QCalendarWidget::paintCell()方法来实现自定义绘制。

这一步骤是自绘制日历控件最最简单、明了的步骤!

示例代码参考:


void QUiCalendarControl::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{QWidget* pTargetWgt = dynamic_cast<QWidget*>(painter->device());if (pTargetWgt){QPoint pt = pTargetWgt->mapFromGlobal(QCursor::pos());m_bHovered = rect.contains(pt);}painter->setRenderHint(QPainter::TextAntialiasing);painter->setRenderHint(QPainter::Antialiasing);painter->setRenderHint(QPainter::SmoothPixmapTransform);//1.绘制背景色(圆形或其他图形)QPainterPath pathBK;pathBK.addEllipse(rcCircle);painter->fillPath(pathBK, backgroundColor(date));//2.绘制边框根据日期的特殊性做特殊绘制if (是今天的日期){painter->save();QPainterPath pathBorder;pathBorder.addEllipse(rcCircle);QPen penBorder;penBorder.setColor(borderColor());penBorder.setWidth(1);painter->setPen(penBorder);painter->drawPath(pathBorder);painter->restore();}if( 是当前选中的日期){}//3.其他一般日期QString strDay = QString::number(date.day());painter->save();painter->drawText(rcCircle, Qt::AlignCenter, strDisplayTxt);painter->restore();//其他绘制*********************省略***************
}

2.定制周信息栏

如果用过QCalendarWidget日历控件,我们会发现,该日历控件的周信息标题定制性极差!也没有任何虚接口可供业务开发者使用。为了达到定制的目标,我们需要结合QCalendarWidget源码去做。

Qt关联源码如下:

QCalendarWidget::QCalendarWidget(QWidget *parent): QWidget(*new QCalendarWidgetPrivate, parent, { })
{Q_D(QCalendarWidget);setAutoFillBackground(true);setBackgroundRole(QPalette::Window);QVBoxLayout *layoutV = new QVBoxLayout(this);layoutV->setContentsMargins(QMargins());d->m_model = new QCalendarModel(this);QTextCharFormat fmt;fmt.setForeground(QBrush(Qt::red));d->m_model->m_dayFormats.insert(Qt::Saturday, fmt);d->m_model->m_dayFormats.insert(Qt::Sunday, fmt);//关键代码!!!!!d->m_view = new QCalendarView(this);d->m_view->setObjectName(QLatin1String("qt_calendar_calendarview"));d->m_view->setModel(d->m_model);d->m_model->setView(d->m_view);d->m_view->setSelectionBehavior(QAbstractItemView::SelectItems);d->m_view->setSelectionMode(QAbstractItemView::SingleSelection);d->m_view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);d->m_view->horizontalHeader()->setSectionsClickable(false);d->m_view->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);d->m_view->verticalHeader()->setSectionsClickable(false);d->m_selection = d->m_view->selectionModel();d->createNavigationBar(this);d->m_view->setFrameStyle(QFrame::NoFrame);d->m_delegate = new QCalendarDelegate(d, this);d->m_view->setItemDelegate(d->m_delegate);d->update();d->updateNavigationBar();setFocusPolicy(Qt::StrongFocus);setFocusProxy(d->m_view);setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);***************省略******************
}

class QCalendarView : public QTableView
{Q_OBJECT
public:QCalendarView(QWidget *parent = nullptr);********省略***********
}

 从源码我们可以看出:

1.所谓的QCalendarWidget日历控件实际上是一个内嵌了QTableView的 widget组件!

2.这个QTableView控件的objectName是qt_calendar_calendarview

所以,我们可以知道在自绘代码中可以通过objectName获取这个tableView对象, 并且可以通过自定义这个tableView的HeadView可以实现定制表头(也就是周信息)

3.定制日历导航栏 

关于定制日历导航栏,这里不再赘述了,其实就是几个按钮控件水平布局一下,而后摆在自绘日历控件的上方构成垂直布局即可!


总结

以上就是今天要分享的:Qt如何实现定制日历组件的内容!

既聊思路,也说代码!我们下次继续分享自定义风格扩展组件!

PS:本专栏所有篇幅涉及的UI扩展组件类,会封装成插件动态库,感兴趣的同学可以留言哦

这篇关于08 Qt自绘制日历控件:摆脱丑的让人无语的原生QCalendarWidget的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760608

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

使用Qt编程QtNetwork无法使用

使用 VS 构建 Qt 项目时 QtNetwork 无法使用的问题 - 摘叶飞镖 - 博客园 (cnblogs.com) 另外,强烈建议在使用QNetworkAccessManager之前看看这篇文章: Qt 之 QNetworkAccessManager踏坑记录-CSDN博客 C++ Qt开发:QNetworkAccessManager网络接口组件 阅读目录 1.1 通用API函数

Qt多语种开发教程

Qt作为跨平台的开发工具,早已应用到各行各业的软件开发中。 今天讲讲,Qt开发的正序怎么做多语言开发。就是说,你设置中文,就中文显示;设置英语就英文显示,设置繁体就繁体显示,设置发育就显示法语等。 开发环境(其实多语种这块根环境没太大关系):win10,Qt.5.12.10 一.先用QtCreator创建一个简单的桌面程序 1.工程就随便命名“LanguageTest”,其他默认。 2.在设计师