Qt日历控件示例-QCalendarWidget

基本说明

QCalendarWidget介绍:
QCalendarWidget 是 Qt 框架中提供的一个日期选择控件,用户可以通过该控件快速选择需要的日期,并且支持显示当前月份的日历。
这里,我们继承了QCalendarWidget,做了一些简单封装和样式调整

1.使用的IDE: QtCreator;
2.qt 版本:Desktop Qt 5.15.2 MSVC2015 64bit
3.效果图:
在这里插入图片描述

QCalendarWidget的属性总结如下:

  • selectedDate:当前选择的日期。
  • minimumDate:可以选择的最早日期。
  • maximumDate:可以选择的最晚日期。
  • firstDayOfWeek:显示为一周的第一天的日期(通常是星期日或星期一)。
  • gridVisible:是否显示网格。
  • selectionMode:用户是否可以选择日期。
  • horizontalHeaderFormat:水平标题中日期名称的格式(例如,“M”, “Mon"或"Monday”)。
  • verticalHeaderFormat:垂直页眉的格式。
  • navigationBarVisible:是否显示日历小部件顶部的导航栏。

pyQt5例子

下面来简单显示一个日历控件,点击不同的星期,会显示不同的心情:

import sys
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QCalendarWidget, QLabel, QVBoxLayout

EMOTION = {
    
                                                                         # 1 
    'Mon': '(╯°Д°)╯︵ ┻━┻',
    'Tue': '(╯ ̄Д ̄)╯╘═╛',
    'Wed': '╭( ̄▽ ̄)╯╧═╧',
    'Thu': '_(:з」∠)_',
    'Fri': '(๑•̀ㅂ•́) ✧',
    'Sat': '( ˘ 3˘)♥',
    'Sun': '(;′༎ຶД༎ຶ`)'
}


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.calendar = QCalendarWidget(self)
        self.calendar.setMinimumDate(QDate(1946, 2, 14))                        # 2
        self.calendar.setMaximumDate(QDate(6666, 6, 6))                         # 3
        # self.calendar.setDateRange(QDate(1946, 2, 14), QDate(6666, 6, 6))
        # self.calendar.setFirstDayOfWeek(Qt.Monday)                            # 4
        # self.calendar.setSelectedDate(QDate(1946, 2, 14))                     # 5
        self.calendar.setGridVisible(True)                                      # 6
        self.calendar.clicked.connect(self.show_emotion_func)                   # 6

        print(self.calendar.minimumDate())                                      # 7
        print(self.calendar.maximumDate())
        print(self.calendar.selectedDate())

        self.label = QLabel(self)                                               # 8
        self.label.setAlignment(Qt.AlignCenter)

        weekday = self.calendar.selectedDate().toString('ddd')                  # 9
        self.label.setText(EMOTION[weekday])

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.calendar)
        self.v_layout.addWidget(self.label)
        
        self.setLayout(self.v_layout)
        self.setWindowTitle('QCalendarWidget')

    def show_emotion_func(self):                                                # 10
        weekday = self.calendar.selectedDate().toString('ddd')
        self.label.setText(EMOTION[weekday])


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

TCalendarWidget.h

#ifndef TCALENDARWIDGET_H
#define TCALENDARWIDGET_H

#include <QCalendarWidget>

class QPushButton;
class QLabel;

class TCalendarWidget : public QCalendarWidget
{
    
    
    Q_OBJECT

public:
    TCalendarWidget(QWidget *parent = 0);
    ~TCalendarWidget();

    void SetHighlightDate(QList<QDate> lstDate);

private:
    void InitControl();
    void InitTopWidget();
    void SetDataLabelTimeText(int year, int month);

signals:
    void SignalSetCalendarTime(const QDate& data);

private slots:
    void SlotBtnClicked();

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

private:
    QPushButton     *m_pBtnLeftYear;
    QPushButton     *m_pBtnLeftMonth;

    QPushButton     *m_pBtnRightYear;
    QPushButton     *m_pBtnRightMonth;

    QLabel          *m_pLblDate;

    QList<QDate>     m_lstHighlightDate;
};


#endif //_T_PROPERTY_H_

TCalendarWidget.cpp

#pragma execution_character_set("utf-8")
#include "TCalendarWidget.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);
    }
};



TCalendarWidget::TCalendarWidget(QWidget *parent)
    : QCalendarWidget(parent)
{
    
    
    InitControl();
}

TCalendarWidget::~TCalendarWidget()
{
    
    

}

void TCalendarWidget::SetHighlightDate(QList<QDate> lstDate)
{
    
    
    m_lstHighlightDate = lstDate;
    updateCells();
}

void TCalendarWidget::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("#FFFFFF"));
    format.setBackground(QColor(27, 33, 43));

    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();

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

void TCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
    
    
    bool bHightlight = false;
    foreach (QDate date1,m_lstHighlightDate)
    {
    
    
        if (date1 == date)
        {
    
    
            bHightlight = true;
        }
    }


    if (date == selectedDate())
    {
    
    
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(QColor("#1B212B"));
        painter->setBrush(QColor("#1B212B"));
        painter->drawRect(rect);

        painter->setPen(QColor("#2678D5"));
        painter->setBrush(QColor("#264974"));
        painter->drawRoundedRect(rect.x() + 6, rect.y() + 2, 24, 24, 2, 2);

        painter->setPen(bHightlight?QColor("#2678D5"): QColor("#FFFFFF"));
        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
    else if (date == QDate::currentDate())
    {
    
    
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(QColor("#1B212B"));
        painter->setBrush(QColor("#1B212B"));
        painter->drawRect(rect);

        painter->setPen(QColor("#2678D5"));
        painter->setBrush(Qt::NoBrush);
        painter->drawRoundedRect(rect.x()+6, rect.y()+2, rect.width()-12, rect.height()-4, 2, 2);


        painter->setPen(bHightlight ? QColor("#2678D5") : QColor("#FFFFFF"));
        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("#3D4E5E"));
        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
    else
    {
    
    
        painter->save();
        painter->setRenderHint(QPainter::Antialiasing);
        painter->setPen(QColor("#1B212B"));
        painter->setBrush(QColor("#1B212B"));
        painter->drawRect(rect);

        painter->setPen(bHightlight ? QColor("#2678D5") : QColor("#FFFFFF"));
        painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
        painter->restore();
    }
}

void TCalendarWidget::InitTopWidget()
{
    
    
    QWidget* pTopWidget = new QWidget(this);
    pTopWidget->setObjectName("CalendarTopWidget");
    pTopWidget->setFixedHeight(36);
    pTopWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QHBoxLayout* pHBoxLayout = new QHBoxLayout;
    pHBoxLayout->setContentsMargins(20, 0, 20, 0);
    pHBoxLayout->setSpacing(10);

    m_pBtnLeftYear = new QPushButton(this);
    m_pBtnRightYear = new QPushButton(this);
    m_pBtnLeftMonth = new QPushButton(this);
    m_pBtnRightMonth = new QPushButton(this);
    m_pLblDate = new QLabel(this);

    m_pBtnLeftYear->setObjectName("CalendarLeftYearBtn");
    m_pBtnRightYear->setObjectName("CalendarRightYearBtn");
    m_pBtnLeftMonth->setObjectName("CalendarLeftMonthBtn");
    m_pBtnRightMonth->setObjectName("CalendarRightMonthBtn");
    m_pLblDate->setObjectName("CommonTextWhite14");

    pHBoxLayout->addWidget(m_pBtnLeftYear);
    pHBoxLayout->addWidget(m_pBtnLeftMonth);
    pHBoxLayout->addStretch();
    pHBoxLayout->addWidget(m_pLblDate);
    pHBoxLayout->addStretch();
    pHBoxLayout->addWidget(m_pBtnRightMonth);
    pHBoxLayout->addWidget(m_pBtnRightYear);
    pTopWidget->setLayout(pHBoxLayout);

    QVBoxLayout *vBodyLayout = qobject_cast<QVBoxLayout *>(layout());
    vBodyLayout->insertWidget(0, pTopWidget);

    connect(m_pBtnLeftYear, SIGNAL(clicked()), this, SLOT(SlotBtnClicked()));
    connect(m_pBtnLeftMonth, SIGNAL(clicked()), this, SLOT(SlotBtnClicked()));
    connect(m_pBtnRightYear, SIGNAL(clicked()), this, SLOT(SlotBtnClicked()));
    connect(m_pBtnRightMonth, SIGNAL(clicked()), this, SLOT(SlotBtnClicked()));

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

void TCalendarWidget::SetDataLabelTimeText(int year, int month)
{
    
    
    m_pLblDate->setText(QString("%1年%2月").arg(year).arg(month));
}

void TCalendarWidget::SlotBtnClicked()
{
    
    
    QPushButton *senderBtn = qobject_cast<QPushButton *>(sender());
    if (senderBtn == m_pBtnLeftYear)
    {
    
    
        showPreviousYear();
    }
    else if (senderBtn == m_pBtnLeftMonth)
    {
    
    
        showPreviousMonth();
    }
    else if (senderBtn == m_pBtnRightYear)
    {
    
    
        showNextYear();
    }
    else if (senderBtn == m_pBtnRightMonth)
    {
    
    
        showNextMonth();
    }
}

样式:

在这里插入图片描述

QString Dialog::GetQss()
{
    
    

    QString str = " QPushButton{font-family: \"Microsoft YaHei\";border:none;background:transparent;}\
    \
    QWidget#CalendarTopWidget \
    { \
        background: #1B212B; \
        border:none; \
        border-bottom: 1px solid #45596B; \
    } \
    \
    QPushButton#CalendarLeftYearBtn \
    { \
        max-height:16px; \
        min-height:16px; \
        max-width:16px; \
        min-width:16px; \
        image: url(STYLESHEET_PIC_PATH/common/year_last_nor.png); \
    } \
    \
    QPushButton#CalendarLeftYearBtn:hover \
    { \
        image: url(STYLESHEET_PIC_PATH/common/year_last_down.png); \
    } \
    \
    \
    QPushButton#CalendarRightYearBtn \
    { \
        max-height:16px; \
        min-height:16px; \
        max-width:16px; \
        min-width:16px; \
        image: url(STYLESHEET_PIC_PATH/common/year_next_nor.png); \
    } \
    \
    QPushButton#CalendarRightYearBtn:hover \
    { \
        image: url(STYLESHEET_PIC_PATH/common/year_next_down.png); \
    } \
    \
    QPushButton#CalendarLeftMonthBtn \
    { \
        max-height:16px; \
        min-height:16px; \
        max-width:16px; \
        min-width:16px; \
        image: url(STYLESHEET_PIC_PATH/common/month_last_nor.png); \
    } \
    \
    QPushButton#CalendarLeftMonthBtn:hover \
    { \
        image: url(STYLESHEET_PIC_PATH/common/month_last_down.png); \
    } \
    \
    QPushButton#CalendarRightMonthBtn \
    { \
        max-height:16px; \
        min-height:16px; \
        max-width:16px; \
        min-width:16px; \
        image: url(STYLESHEET_PIC_PATH/common/month_next_nor.png); \
    } \
    \
    QPushButton#CalendarRightMonthBtn:hover \
    { \
        image: url(STYLESHEET_PIC_PATH/common/month_next_down.png); \
    } \
    QLabel#CommonTextWhite14 \
    { \
        color: #ffffff; \
        font-size: 14px; \
    } \
    ";

    str.replace("STYLESHEET_PIC_PATH/common/", "://res/");
    return str;
}

图片资源

图片下载

调用代码

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    
    
    ui->setupUi(this);
    setWindowTitle(tr("Calendar Widget"));
    setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
    // 样式 1
    setStyleSheet(GetQss());
    
    m_pCalender = new TCalendarWidget(this);
    QHBoxLayout* pMainLayout = new QHBoxLayout(this);
    pMainLayout->setMargin(0);
    pMainLayout->addWidget(m_pCalender);
}

猜你喜欢

转载自blog.csdn.net/p309654858/article/details/132616465
今日推荐