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

相关文章

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

go rate 原生标准限速库的使用

《gorate原生标准限速库的使用》本文主要介绍了Go标准库golang.org/x/time/rate实现限流,采用令牌桶算法控制请求速率,提供Allow/Reserve/Wait方法,具有一定... 目录介绍安装API介绍rate.NewLimiter:创建限流器limiter.Allow():请求是否

Qt之QMessageBox的具体使用

《Qt之QMessageBox的具体使用》本文介绍Qt中QMessageBox类的使用,用于弹出提示、警告、错误等模态对话框,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.简单介绍3.常见函数4.按钮类型(QMessage::StandardButton)5.分步骤实现弹窗6.总结1.引言

Qt中Qfile类的使用

《Qt中Qfile类的使用》很多应用程序都具备操作文件的能力,包括对文件进行写入和读取,创建和删除文件,本文主要介绍了Qt中Qfile类的使用,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.QFile文件操作3.演示示例3.1实验一3.2实验二【演示 QFile 读写二进制文件的过程】4.

WinForms中主要控件的详细使用教程

《WinForms中主要控件的详细使用教程》WinForms(WindowsForms)是Microsoft提供的用于构建Windows桌面应用程序的框架,它提供了丰富的控件集合,可以满足各种UI设计... 目录一、基础控件1. Button (按钮)2. Label (标签)3. TextBox (文本框

QT6中绘制UI的两种方法详解与示例代码

《QT6中绘制UI的两种方法详解与示例代码》Qt6提供了两种主要的UI绘制技术:​​QML(QtMeta-ObjectLanguage)​​和​​C++Widgets​​,这两种技术各有优势,适用于不... 目录一、QML 技术详解1.1 QML 简介1.2 QML 的核心概念1.3 QML 示例:简单按钮

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否