QT之自定义日历

日##QT之自定义日历
[TOC]

简述

~~~~~~样式只供学习使用~~~~

效果图

这里写图片描述

代码

//qcustomcalendarwidget.h

#ifndef QCUSTOMCALENDARWIDGET_H
#define QCUSTOMCALENDARWIDGET_H

#include <QCalendarWidget>

class QPushButton;
class QLabel;
class QCustomCalendarWidget : public QCalendarWidget
{
    Q_OBJECT

public:
    QCustomCalendarWidget(QWidget *parent);
    ~QCustomCalendarWidget();

private:
    void initControl();
    void initTopWidget();
    void initBottomWidget();
    void setDataLabelTimeText(int year, int month);

signals:
    void signalSetCalendarTime(const QDate& data);

private slots:
    void onbtnClicked();

protected:
    void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;

private:
    QPushButton* m_leftYearBtn;
    QPushButton* m_leftMonthBtn;

    QPushButton* m_rightYearBtn;
    QPushButton* m_rightMonthBtn;

    QPushButton* m_ensureBtn;
    QPushButton* m_toDayBtn;

    QLabel* m_dataLabel;
};
//qcustomcalendarwidget.cpp

#include "qcustomcalendarwidget.h"

#include <QLocale> 
#include <QPainter>
#include <QTextCharFormat>
#include <QProxyStyle>
#include <QTableView>
#include <QLayout>
#include <QPushButton>
#include <QLabel>

class QCustomStyle : public QProxyStyle
{
public:
    QCustomStyle(QWidget *parent){
        setParent(parent);
    };

private:
    void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
        QPainter *painter, const QWidget *widget) const
    {
        if (element == PE_FrameFocusRect)
        {
            return;
        }
        QProxyStyle::drawPrimitive(element, option, painter, widget);
    }
};

QCustomCalendarWidget::QCustomCalendarWidget(QWidget *parent)
    : QCalendarWidget(parent)
{
    initControl();
}

QCustomCalendarWidget::~QCustomCalendarWidget()
{

}

void QCustomCalendarWidget::initControl()
{
    layout()->setSizeConstraint(QLayout::SetFixedSize);
    setLocale(QLocale(QLocale::Chinese));
    setNavigationBarVisible(false);
    setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
    setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
    setStyle(new QCustomStyle(this));

    QTextCharFormat format;
    format.setForeground(QColor(160, 160, 160));
    format.setBackground(QColor(255, 255, 255));

    setHeaderTextFormat(format);
    setWeekdayTextFormat(Qt::Saturday, format);
    setWeekdayTextFormat(Qt::Sunday,   format);
    setWeekdayTextFormat(Qt::Monday,   format);
    setWeekdayTextFormat(Qt::Tuesday,  format);
    setWeekdayTextFormat(Qt::Wednesday,format);
    setWeekdayTextFormat(Qt::Thursday, format);
    setWeekdayTextFormat(Qt::Friday,   format);

    initTopWidget();
    initBottomWidget();

    connect(this, &QCalendarWidget::currentPageChanged, [this](int year, int month){
        setDataLabelTimeText(year, month);
    });
}

void QCustomCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
    if (date == selectedDate())
    {
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(Qt::NoPen);
        painter->setBrush(QColor(0, 145, 255));

        painter->drawRoundedRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6, 3, 3);
        painter->setPen(QColor(255, 255, 255));

        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
    else if (date == QDate::currentDate())
    {
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(Qt::NoPen);
        painter->setBrush(QColor(0, 161, 255));
        painter->drawRoundedRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6, 3, 3);
        painter->setBrush(QColor(255, 255, 255));
        painter->drawRoundedRect(rect.x() + 1, rect.y() + 4, rect.width() - 2, rect.height() - 8, 2, 2);
        painter->setPen(QColor(0, 161, 255));

        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
    else if (date < minimumDate() || date > maximumDate())
    {
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(Qt::NoPen);
        painter->setBrush(QColor(249, 249, 249));

        painter->drawRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6);
        painter->setPen(QColor(220, 220, 220));

        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
    else
    {
        __super::paintCell(painter, rect, date);
    }
}

void QCustomCalendarWidget::initTopWidget()
{
    QWidget* topWidget = new QWidget(this);
    topWidget->setObjectName("CalendarTopWidget");
    topWidget->setFixedHeight(40);
    topWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QHBoxLayout* hboxLayout = new QHBoxLayout;
    hboxLayout->setContentsMargins(12, 0, 12, 0);
    hboxLayout->setSpacing(4);

    m_leftYearBtn   = new QPushButton(this);
    m_leftMonthBtn  = new QPushButton(this);
    m_rightYearBtn  = new QPushButton(this);
    m_rightMonthBtn = new QPushButton(this);
    m_dataLabel     = new QLabel(this);

    m_leftYearBtn->setObjectName("CalendarLeftYearBtn");
    m_leftMonthBtn->setObjectName("CalendarLeftMonthBtn");
    m_rightYearBtn->setObjectName("CalendarRightYearBtn");
    m_rightMonthBtn->setObjectName("CalendarRightMonthBtn");
    m_dataLabel->setObjectName("CalendarDataLabel");

    m_leftYearBtn->setFixedSize(16, 16);
    m_leftMonthBtn->setFixedSize(16, 16);
    m_rightYearBtn->setFixedSize(16, 16);
    m_rightMonthBtn->setFixedSize(16, 16);

    hboxLayout->addWidget(m_leftYearBtn);
    hboxLayout->addWidget(m_leftMonthBtn);
    hboxLayout->addStretch();
    hboxLayout->addWidget(m_dataLabel);
    hboxLayout->addStretch();
    hboxLayout->addWidget(m_rightMonthBtn);
    hboxLayout->addWidget(m_rightYearBtn);
    topWidget->setLayout(hboxLayout);

    //这里见下图1
    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
    vBodyLayout->insertWidget(0, topWidget);

    connect(m_leftYearBtn,   SIGNAL(clicked()),  this, SLOT(onbtnClicked()));
    connect(m_leftMonthBtn,  SIGNAL(clicked()),  this, SLOT(onbtnClicked()));
    connect(m_rightYearBtn,  SIGNAL(clicked()),  this, SLOT(onbtnClicked()));
    connect(m_rightMonthBtn, SIGNAL(clicked()),  this, SLOT(onbtnClicked()));

    setDataLabelTimeText(selectedDate().year(), selectedDate().month());
}

void QCustomCalendarWidget::initBottomWidget()
{
    QWidget* bottomWidget = new QWidget(this);
    bottomWidget->setObjectName("CalendarBottomWidget");
    bottomWidget->setFixedHeight(40);
    bottomWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QHBoxLayout* hboxLayout = new QHBoxLayout;
    hboxLayout->setContentsMargins(12, 0, 12, 0);
    hboxLayout->setSpacing(6);

    m_ensureBtn = new QPushButton(this);
    m_ensureBtn->setObjectName("CalendarEnsureBtn");
    m_ensureBtn->setFixedSize(40, 22);
    m_ensureBtn->setText(QStringLiteral("确定"));

    m_toDayBtn = new QPushButton(this);
    m_toDayBtn->setObjectName("CalendarTodayBtn");
    m_toDayBtn->setFixedSize(40, 22);
    m_toDayBtn->setText(QStringLiteral("现在"));

    hboxLayout->addStretch();
    hboxLayout->addWidget(m_toDayBtn);
    hboxLayout->addWidget(m_ensureBtn);
    bottomWidget->setLayout(hboxLayout);

    //这里见下图1
    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
    vBodyLayout->addWidget(bottomWidget);

    connect(m_ensureBtn, &QPushButton::clicked, [this](){
        emit signalSetCalendarTime(selectedDate());
        emit activated(selectedDate());
    });

    connect(m_toDayBtn, &QPushButton::clicked, [this](){
        showToday();
    });
}

void QCustomCalendarWidget::setDataLabelTimeText(int year, int month)
{
    m_dataLabel->setText(QStringLiteral("%1年%2月").arg(year).arg(month));
}

void QCustomCalendarWidget::onbtnClicked()
{
    QPushButton *senderBtn = qobject_cast<QPushButton *>(sender());
    if (senderBtn == m_leftYearBtn)
    {
        showPreviousYear();
    }
    else if (senderBtn == m_leftMonthBtn)
    {
        showPreviousMonth();
    }
    else if (senderBtn == m_rightYearBtn)
    {
        showNextYear();
    }
    else if (senderBtn == m_rightMonthBtn)
    {
        showNextMonth();
    }
}
//QCustomTimeEdit.cpp

QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate(), this);
    QCustomCalendarWidget* calendarWidget = new QCustomCalendarWidget(this);
    dateEdit->setCalendarPopup(true);  // 日历弹出
    dateEdit->setCalendarWidget(calendarWidget);
    dateEdit->setMinimumDate(QDate::currentDate().addDays(0));  // 0天
    dateEdit->setMaximumDate(QDate::currentDate().addDays(365));  // +365天
    dateEdit->setContextMenuPolicy(Qt::NoContextMenu);
    dateEdit->setFixedSize(150, 26);
    dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    calendarWidget->disconnect(SIGNAL(selectionChanged()));
    calendarWidget->disconnect(SIGNAL(clicked(QDate)));

    connect(calendarWidget, &QCustomCalendarWidget::signalSetCalendarTime, [dateEdit](const QDate& data){
        dateEdit->setDate(data);
    });

图1:QCalendarWidget源码
这里写图片描述

通过获取此布局,给自定义的QCalendarWidget中添加自定义的控件。

结尾

只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~
———————需要工程文件的,加我工作号QQ:3246214072———————

  • 40
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
### 回答1: Qt自带的QCalendarWidget类提供了一种简单的日历控件,但是功能上比较基础。如果需要更多功能,可以自定义一个增强版的日历控件。 首先,可以通过继承QCalendarWidget类来创建一个新的自定义日历控件类。然后在新的类中添加一些额外的功能。例如,可以添加一个日期选择范围的功能,让用户只能在指定的日期范围内选择日期。 另外,可以添加一个月份/年份选择器,让用户可以快速切换到其他月份或年份。通过添加一个组合框或者切换按钮来实现这个功能。 还可以增加一个自定义的日期标记功能,让用户可以为某些特定日期添加标记,例如节假日、重要事件等。这样用户在看日历的时候就可以一目了然地知道哪些日期是特殊的。 如果希望日历控件适应不同的主题或者界面风格,还可以添加样式自定义的功能,让用户可以根据自己的需求来设置日历的外观样式。 另外,还可以添加一些其他的功能,如设置默认选择的日期、在某些特定日期显示特定信息等。 总之,通过继承QCalendarWidget类并添加上述功能,我们可以创建一个更加强大和个性化的日历控件,满足各种不同的需求。 ### 回答2: Qt中的日历组件是一个非常实用的工具,但是有时候我们可能需要对其进行一些自定义和增强。以下是关于如何创建一个自定义的增强版Qt日历的一些建议: 1. 自定义外观:通过使用Qt的样式表功能,你可以自定义日历的外观,包括背景颜色、字体、边框等。你可以根据自己的需求来设计一个与应用程序风格一致的日历。 2. 添加额外功能:你可以在日历中添加一些额外的功能,如快速切换到特定日期、显示公众假日等。通过添加自定义的按钮或选项,用户可以方便地选择他们感兴趣的日期和事件。 3. 自定义事件:你可以为特定日期添加自定义事件,如生日、会议等。通过添加事件标记或图标,用户可以轻松地查看和管理他们的日程安排。 4. 跨平台支持:Qt提供了对多个平台的支持,包括 Windows、Linux和MacOS等。确保你的自定义增强版日历在不同平台上都能正常运行和显示。 5. 多语言支持:如果你的应用程序需要支持多种语言环境,你可以使用Qt的国际化功能来实现日历的多语言显示。这样,用户可以根据自己的语言偏好来使用你的应用程序。 6. 响应式设计:确保你的日历在不同窗口尺寸和屏幕分辨率下都能够自适应,并且可以正确地显示和操作。这样,用户无论是在手机、平板还是计算机上使用你的应用程序,都能够获得良好的体验。 通过以上的一些自定义和增强,你可以创建一个更加灵活和强大的Qt日历组件,满足用户的日历需求,并提升应用程序的用户体验。 ### 回答3: Qt是一款功能强大的GUI(图形用户界面)开发框架,它提供了丰富的工具和组件,可以快速轻松地创建各种应用程序。其中,日历是常用的UI控件之一。 自定义日历的增强版是使用Qt框架自定义开发的一个升级版本,具有更多功能和更好的用户体验。 首先,增强版的自定义日历具有丰富的样式选择。用户可以根据自己的喜好和需求选择不同的颜色、字体、背景等等。这样,用户可以根据自己的个性化需求,将日历的外观设置得更加独特和吸引人。 其次,增强版的自定义日历支持更多的交互方式。传统的日历只能通过单击或滚动的方式来选择日期,而增强版的自定义日历可以通过手指滑动、手势缩放等更多的方式来操作。这样,用户可以更加灵活地浏览和选择日期,提升了用户的操作体验。 再次,增强版的自定义日历具有更多的功能。除了基本的日期选择和显示外,增强版的自定义日历也可以提供天气预报、节假日提醒、待办事项等功能。用户可以通过简单的操作,在日历上查看天气信息、添加和管理待办事项等,方便快捷地掌握自己的日程安排。 此外,增强版的自定义日历还可以与其他应用程序进行集成。例如,用户可以将日历与电子邮件或社交媒体应用程序相连,以便在特定日期或活动之前接收提醒或通知。这样,用户可以更好地管理自己的时间和安排。 总之,Qt自定义日历的增强版具有更多的样式选择、交互方式、功能和与其他应用程序的集成,提供了更好的用户体验和更全面的功能。无论是对个人用户还是商业用户来说,这都是一个非常实用和有价值的工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雨田哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值