Basic instructions
Introduction to QCalendarWidget:
QCalendarWidget is a date selection control provided in the Qt framework. Users can quickly select the required date through this control, and supports displaying the calendar of the current month.
Here, we inherit QCalendarWidget and make some simple encapsulation and style adjustments
1. IDE used: QtCreator;
2. qt version: Desktop Qt 5.15.2 MSVC2015 64bit
3. Rendering:
The properties of QCalendarWidget are summarized as follows:
- selectedDate: The currently selected date.
- minimumDate: The earliest date that can be selected.
- maximumDate: The latest date that can be selected.
- firstDayOfWeek: The date displayed as the first day of the week (usually Sunday or Monday).
- gridVisible: Whether to display the grid.
- selectionMode: Whether the user can select dates.
- horizontalHeaderFormat: The format for date names in horizontal headers (for example, "M", "Mon" or "Monday").
- verticalHeaderFormat: The format of the vertical header.
- navigationBarVisible: Whether to display the navigation bar at the top of the calendar widget.
pyQt5 example
Let's simply display a calendar control. Clicking on different weeks will display different moods:
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();
}
}
style:
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;
}
Picture resources
calling code
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);
}