基本说明
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);
}