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

相关文章

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

如何用Python绘制简易动态圣诞树

《如何用Python绘制简易动态圣诞树》这篇文章主要给大家介绍了关于如何用Python绘制简易动态圣诞树,文中讲解了如何通过编写代码来实现特定的效果,包括代码的编写技巧和效果的展示,需要的朋友可以参考... 目录代码:效果:总结 代码:import randomimport timefrom math