基于qt中QCalendarWidget的双日历时间范围选择控件(自定义)

控件预览:

在这里插入图片描述
控件基于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 &param);
    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位动态库(不必修改样式时可直接使用)
地址:
点击跳至下载页

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颢师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值