控件预览:
控件基于QT设计,单击日历设置时间范围起点,再次单击日历设置时间范围终点;
当起止时间为同一天时,所选日期右上角显示“单”字样:
控件设计说明:
控件基于QT中QDialog控件:
1、 由两基本QCalendarWidget拼接而成;
2、 可独立修改QCalendarWidget样式,包括底纹,背景色,选中显示字样,选取时间范围颜色等;
class ScopeCalendar : public QDialog
{
Q_OBJECT
public:
explicit ScopeCalendar(QWidget *parent = nullptr);
~ScopeCalendar();
private:
Ui::ScopeCalendar *ui;
/*!
* \brief initAfterOpen 初始化调用
*/
//初始化操作
void initAfterOpen();
//槽函数连接
void setConnection();
void rlBeClicked(std::pair<QString,QDate> info);
DateSelected _selectedDate;
signals:
void sendResult(QString dateRange);
};
最终结果由信号sendResult发送,调用及解析方式如下:
auto calendar=new ScopeCalendar();
connect(calendar,&ScopeCalendar::sendResult,[=](QString result){_result=result;});
calendar->exec();
QStringList list=_result.split(QString::fromLocal8Bit(" 至 "));
其中list[0]为起始时间,list[1]为终止时间。
关于自定义QCalendarWidget样式说明:
#include "qpainter.h"
#include <QObject>
#include "QCalendarWidget"
/*!
* \brief The drawCalendarCellParam class 用于绘制单元格
*/
class DrawCalendarCellParam
{
friend class MyCalendarWidget;
public:
/*!
* \brief background 背景颜色
*/
QColor _background=QColor(255,255,255);
/*!
* \brief _numColor 文字颜色
*/
QColor _numColor=QColor(0,0,0);
/*!
* \brief _topRightCharactersColor 右上角起止字体颜色
*/
QColor _topRightCharactersColor=Qt::red;
/*!
* \brief _textureColor 底纹颜色
*/
QColor _textureColor=Qt::gray;
private:
/*!
* \brief _isEndOrStart 是否为起止日期
*/
bool _isEndOrStart=false;
/*!
* \brief _topRightCharacters 起止字符设置
*/
Qt::BrushStyle _textureStyle =Qt::FDiagPattern;
};
class MyCalendarWidget : public QCalendarWidget
{
Q_OBJECT
public:
MyCalendarWidget(QWidget* parent=nullptr);
virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;
void setParam(const DrawCalendarCellParam ¶m);
void clearAllTopRight();
void upDateCellForTopRight(QDate date);
void setStart(const QDate &start);
void setEnd(const QDate &end);
void setSelectedColorBetweenTwoDatas(QDate start,QDate end);
bool eventFilter(QObject *obj, QEvent *event);
private:
DrawCalendarCellParam _param;
QDate _start;
QDate _end;
QDate _colorStart;
QDate _colorEnd;
};
通过重写virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const函数,实现自定义控件样式的实现:
void MyCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
//设置底色
painter->setBrush(QBrush(_param._background,Qt::SolidPattern));
painter->drawRect(rect);
//设置底纹
if(this->monthShown()!=date.month())
{
painter->setBrush(QBrush(_param._textureColor,_param._textureStyle));
painter->drawRect(rect);
}
//书写日历数字
painter->setFont(QFont("宋体",rect.width()/3));
painter->setPen(_param._numColor);
painter->drawText(rect,Qt::AlignHCenter|Qt::AlignVCenter,QString::number(date.day()));
//书写右上角起止字样
if(date==_start&&date!=_end&&this->monthShown()==date.month())
{
painter->setFont(QFont("宋体",rect.width()/6));
painter->setPen(_param._topRightCharactersColor);
painter->drawText(QRect(rect.x()+rect.width()*2/3,rect.topLeft().y(),rect.width()/3,rect.width()/3),
Qt::AlignHCenter|Qt::AlignVCenter,QString::fromLocal8Bit("起"));
painter->setPen(Qt::black);
painter->setBrush(QBrush(QColor(0,255,255,50),Qt::SolidPattern));
painter->drawRect(rect);
}
if(date==_end&&date==_start&&this->monthShown()==date.month()&&date.isValid())
{
painter->setFont(QFont("宋体",rect.width()/6));
painter->setPen(_param._topRightCharactersColor);
painter->drawText(QRect(rect.x()+rect.width()*2/3,rect.topLeft().y(),rect.width()/3,rect.width()/3),
Qt::AlignHCenter|Qt::AlignVCenter,QString::fromLocal8Bit("单"));
painter->setPen(Qt::black);
painter->setBrush(QBrush(QColor(0,255,255,50),Qt::SolidPattern));
painter->drawRect(rect);
}
else if(date==_end&&date!=_start&&this->monthShown()==date.month())
{
painter->setFont(QFont("宋体",rect.width()/6));
painter->setPen(_param._topRightCharactersColor);
painter->drawText(QRect(rect.x()+rect.width()*2/3,rect.topLeft().y(),rect.width()/3,rect.width()/3),
Qt::AlignHCenter|Qt::AlignVCenter,QString::fromLocal8Bit("止"));
painter->setPen(Qt::black);
}
if(_colorStart.isValid()&&_colorEnd.isValid()&&date<=_colorEnd&&date>_colorStart&&this->monthShown()==date.month())
{
painter->setBrush(QBrush(QColor(0,255,255,50),Qt::SolidPattern));
painter->drawRect(rect);
}
}
注:关于拦截QCalendarWidget控件中鼠标滚轮信号QEvent::Wheel的方法:
由于想禁用在鼠标滚轮滚动时,QCalendarWidget自带的翻页效果,经尝试,直接在QCalendarWidget类或其子类中使用事件过滤器拦截没有效果,应对CalendarWidget类中的成员类变量QTableView类进行拦截,方法是使用findChildren函数,寻找QTableView类,并对其中的viewport()部分添加事件过滤器。
for(auto each:this->findChildren<QTableView*>())
{
each->viewport()->installEventFilter(this);
}
之后设置qt事件过滤器进行拦截;
bool MyCalendarWidget::eventFilter(QObject *obj, QEvent *event)
{
if(event->type()==QEvent::Wheel)
{
return true;
}
else
{
return QWidget::eventFilter(obj,event);
}
}
源码及动态库下载:
下载内容包含:
1、控件源代码(qtcreator工程源码)
2、Windows下32位及64位动态库(不必修改样式时可直接使用)
地址:
点击跳至下载页