Qt自定义实现的日历控件 您所在的位置:网站首页 简单的台历制作 Qt自定义实现的日历控件

Qt自定义实现的日历控件

2024-07-09 08:37| 来源: 网络整理| 查看: 265

QDateTimeEdit 或 QCalendarWidget 在美化界面时都比较难实现,且很多效果都无法自定义,比如日历背景外发光的效果,于是自定义实现一个日志,所有的效果都可以自定已实现。棒棒的。

注:此博客虽为原创,但控件的自定实现为参考博主lynnhua_的一篇Qt 制作带农历的日历来实现的效果,源文地址:https://blog.csdn.net/nigoole/article/details/51320239。

先给各位看下实现后效果吧。

1. 先自定义了一个按钮,继承自QPushButton,并进行美化,让其看起来像是一个输入框。

class CalendarWidget; class DateTimeInputButton : public QPushButton { Q_OBJECT public: explicit DateTimeInputButton(QWidget *parent = 0); void setText(const QString &text); public slots: void showCalendarWidget(); QDateTime dateTime() const; QDate date() const; QTime time() const; void setDateTime(const QDateTime &dateTime); void setDate(const QDate &date); void setTime(const QTime &time); void setDateTimeRange(const QDateTime &min, const QDateTime &max); void dateTimeRange(QDateTime &min, QDateTime &max); signals: void dateTimeChanged(const QDateTime &dateTime); protected: void initStyleSheet(); void initConnect(); protected slots: void slotDayClicked(const QDateTime & dt); private: CalendarWidget* pCldrWgt; QDateTime m_dateTime; QString m_strFormat; }; DateTimeInputButton::DateTimeInputButton(QWidget *parent) : QPushButton(parent) { pCldrWgt = new CalendarWidget(this, QMenu().windowFlags() | Qt::FramelessWindowHint); initStyleSheet(); initConnect(); } void DateTimeInputButton::setText(const QString &text) { if(text.isEmpty() || QDateTime::fromString(text, m_strFormat).isNull()) return; QPushButton::setText(text); } void DateTimeInputButton::showCalendarWidget() { QPoint pt(-17, height() - 10); pt = mapToGlobal(pt); pCldrWgt->jumpToDateTime(m_dateTime); pCldrWgt->move(pt); pCldrWgt->show(); } QDateTime DateTimeInputButton::dateTime() const { return m_dateTime; } QDate DateTimeInputButton::date() const { return m_dateTime.date(); } QTime DateTimeInputButton::time() const { return m_dateTime.time(); } void DateTimeInputButton::setDateTime(const QDateTime &dateTime) { m_dateTime = dateTime; setText(m_dateTime.toString(m_strFormat)); } void DateTimeInputButton::setDate(const QDate &date) { setDateTime(QDateTime(date, m_dateTime.time())); } void DateTimeInputButton::setTime(const QTime &time) { setDateTime(QDateTime(m_dateTime.date(), time)); } void DateTimeInputButton::setDateTimeRange(const QDateTime &min, const QDateTime &max) { pCldrWgt->setDateTimeRange(min, max); } void DateTimeInputButton::dateTimeRange(QDateTime &min, QDateTime &max) { pCldrWgt->dateTimeRange(min, max); } void DateTimeInputButton::initStyleSheet() { setStyleSheet(QString( ".DateTimeInputButton" "{" "border: 1px solid #00d2ff; " "border-radius: 3px; " "background-color:#083590; " "min-height: 26px; " "padding-left: 7px; " "color:#ddf5ff; " "font-size:14px; " "border-radius: 3px; " "text-align : left; " "}" )); m_strFormat = QString("yyyy/MM/dd hh:mm"); m_dateTime = QDateTime::currentDateTime(); QString text = m_dateTime.toString(m_strFormat); QPushButton::setText(text); } void DateTimeInputButton::initConnect() { connect(this, &QAbstractButton::clicked, this, &DateTimeInputButton::showCalendarWidget); connect(pCldrWgt, &CalendarWidget::dayClicked, this, &DateTimeInputButton::slotDayClicked); } void DateTimeInputButton::slotDayClicked(const QDateTime &dt) { m_dateTime = dt; setText(dt.toString(m_strFormat)); }

2. 再实现按钮点击后,弹出的日历界面

class CalendarWidget : public QWidget { Q_OBJECT public: explicit CalendarWidget(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); ~CalendarWidget(); int year() const; void setYear(int year); int month() const; void setMonth(int month); int day() const; void setDay(int day); int hour() const; void setHour(int h); int minute(); void setMinute(int m); void jumpToDateTime(const QDateTime& dt); void setDateTimeRange(const QDateTime &min, const QDateTime &max); void dateTimeRange(QDateTime &min, QDateTime &max); signals: void dayClicked(const QDateTime&); void selectDayChanged(const QDateTime&); private: QVBoxLayout *verLayoutCalendar; QWidget *widgetTitle; QComboBox* comboBox_Year; QComboBox* comboBox_Month; QWidget *widgetWeek; QLabel *labelWeek[Week]; QHBoxLayout *horLayoutWeek; QWidget *widgetBody; DayLabel *labelDay[42]; QGridLayout *gridLayoutBody; QWidget *widgetRight; QLabel *labelShowToday; QLabel *labelShowWeek; QLabel *labelShowDay; QLabel *labelShowNYear; QLabel *labelShowLunarDate; QLabel *labelSpacer; QLabel *labelScheduleTitle; QLabel *labelSchedule; QWidget* widget_bottom; QComboBox* comboBox_Hour; QComboBox* comboBox_min; QLabel* label_splite; QPushButton* pushBtn_Rtn; QPushButton* pushBtn_Now; QPushButton* pushBtn_Ok; QVBoxLayout *verlayoutWidgetRight; QHBoxLayout *horLayoutGlobal; private: int m_nYear; int m_nMonth; int m_nDay; int m_nHour; int m_nMin; QDateTime m_maxDt; QDateTime m_minDt; DayLabel* m_pCrtSelect; private: void initWidget(); void initDate(); void initStyleSheet(); void UpdateYear(); DayLabel* getDayLabel(int y, int m, int d); void changeCurrentSelectDay(); protected: virtual void paintEvent(QPaintEvent* e); private slots: void sltDayClicked(int type, int day); void sltShowPrevMonth(); void sltShowNextMonth(); void sltComboBoxDateChange(int); void sltComboBoxTimeChange(int); void slotPushBtnRtn(); void slotPushBtnNow(); void slotPushBtnOk(); };

// /// \brief DayLabel::DayLabel /// \param parent static const QString s_strWeek[] = { LC_STR("周日"), LC_STR("周一"), LC_STR("周二"), LC_STR("周三"), LC_STR("周四"), LC_STR("周五"), LC_STR("周六"), }; CalendarWidget::CalendarWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { // 获取当前年月日 m_nYear = QDate::currentDate().year(); m_nMonth = QDate::currentDate().month(); m_nDay = QDate::currentDate().day(); m_pCrtSelect = NULL; // 设置默认日期范围 m_minDt = QDateTime(QDate(1900,1,1)); m_maxDt = QDateTime(QDate(2099,12,31), QTime(23, 59, 59)); initWidget(); initDate(); initStyleSheet(); UpdateYear(); } CalendarWidget::~CalendarWidget() { } void CalendarWidget::initStyleSheet() { setStyleSheet(QString( ".CalendarWidget{" "border-image:url(:/img/img/bk.png);" "} " "QLabel{color:#cadfff; font-size:12px;} " "QLabel#labelWeekend{color:#00caff;} " "QLable#label_splite{font: bold 14px;} " "QWidget#widgetTitle{background-color:#061f65;} " "QComboBox{background-color: transparent; selection-background-color: transparent; color:#ffffff; font-size: 14px; min-height: 20px; selection-text-align: right;} " "QComboBox::down-arrow{ image:url(:/img/img/ComboBoxArrow.png); } " "QComboBox::down-arrow:on{ top: 1px; left: 1px; } QComboBox::drop-down{ width: 26px; border:none; } " "QComboBox QAbstractItemView {border: none; outline:0px;} QComboBox QAbstractItemView::item{ height: 26px; min-height:26px;} " "QComboBox QAbstractItemView::item:selected{ background-color: #0087f1; color: #e6ebf1;} QComboBox QAbstractItemView::item:!selected {background-color: #e6ebf1; color: #000000;} " "QPushButton{ " " background-color: transparent; " " border-radius: 11px; " " border: 1px solid #259bf3; " " font-size: 12px; " " font-family: AdobeHeitiStd-Regular; " " color:#ffffff; " "} " "QPushButton:hover{background-color: rgba(37, 155, 243, 0.41);} " "QPushButton:pressed{background-color: rgba(37, 155, 243, 0.99);} " "QScrollBar:vertical{width:12px;background:rgba(0,0,0,0%);margin:0px,0px,0px,0px;padding-top:9px;padding-bottom:9px;} " "QScrollBar::handle:vertical{width:12px;border-image:url(:/devicesetting/image/devicesetting/ver_scroll_handle.png);border-radius:0px;min-height:20;}" "QScrollBar::handle:vertical:hover{width:20px;border-image:url(:/devicesetting/image/devicesetting/ver_scroll_handle.png);border-radius:0px;min-height:20;}" "QScrollBar::add-line:vertical,QScrollBar::add-line:vertical:hover{height:9px;width:8px;border-image:url(:/devicesetting/image/devicesetting/scroll_down.png);subcontrol-position:bottom;background:rgba(2,97,203,100%);}" "QScrollBar::sub-line:vertical,QScrollBar::sub-line:vertical:hover{height:9px;width:8px;border-image:url(:/devicesetting/image/devicesetting/scroll_up.png);subcontrol-position:top;background:rgba(2,97,203,100%);}" "QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{background:rgba(2,97,203,100%);}" "QScrollBar:horizontal{max-height:12px;background:transparent;padding-left:9px;padding-right:9px;}" "QScrollBar::handle:horizontal{height:9px;min-width:10px;border-radius:0px;border-image:url(:/devicesetting/image/devicesetting/hor_scroll_handle.png);}" "QScrollBar::handle:horizontal:hover{border-image:url(:/devicesetting/image/devicesetting/hor_scroll_handle.png);}" "QScrollBar::sub-line:horizontal,QScrollBar::sub-line:horizontal:hover{height:9px;width:9px;border-image:url(:/devicesetting/image/devicesetting/scroll_left.png);subcontrol-position:left;background:rgba(2,97,203,100%);}" "QScrollBar::add-line:horizontal,QScrollBar::add-line:horizontal:hover{height:9px;width:9px;border-image:url(:/devicesetting/image/devicesetting/scroll_right.png);subcontrol-position:right;background:rgba(2,97,203,100%);}" "QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal{background:rgba(2,97,203,100%);}" )); setAutoFillBackground(false); setAttribute(Qt::WA_TranslucentBackground, true); } void CalendarWidget::UpdateYear() { comboBox_Year->clear(); QDate d1 = m_minDt.date(); QDate d2 = m_maxDt.date(); for (int i = d1.year(); iaddItem(QString::number(i)); } } DayLabel *CalendarWidget::getDayLabel(int y, int m, int d) { int nWeek = Date::getFirstDayOfWeek(y, m); nWeek = (0 == nWeek ? 7 : nWeek); // 显示当前天数 return labelDay[d + nWeek - 1]; } void CalendarWidget::changeCurrentSelectDay() { DayLabel *pLabel = getDayLabel(m_nYear, m_nMonth, m_nDay); if(m_pCrtSelect) m_pCrtSelect->setSelected(false); m_pCrtSelect = pLabel; if(m_pCrtSelect) m_pCrtSelect->setSelected(true); } void CalendarWidget::paintEvent(QPaintEvent *e) { QPainter p(this); p.drawPixmap(0, 0, QPixmap(":/img/img/bk.png").scaled(size())); QWidget::paintEvent(e); } int CalendarWidget::year() const { return m_nYear; } void CalendarWidget::setYear(int nYear) { m_nYear = nYear; disconnect(comboBox_Year, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int))); comboBox_Year->setCurrentIndex(comboBox_Year->findText(QString::number(nYear))); connect(comboBox_Year, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int))); } int CalendarWidget::month() const { return m_nMonth; } void CalendarWidget::setMonth(int nMonth) { m_nMonth = nMonth; disconnect(comboBox_Month, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int))); comboBox_Month->setCurrentIndex(nMonth - 1); connect(comboBox_Month, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int))); } int CalendarWidget::day() const { return m_nDay; } void CalendarWidget::setDay(int nDay) { m_nDay = nDay; } int CalendarWidget::hour() const { return m_nHour; } void CalendarWidget::setHour(int h) { m_nHour = h; disconnect(comboBox_Hour, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int))); comboBox_Hour->setCurrentIndex(h); connect(comboBox_Hour, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int))); } int CalendarWidget::minute() { return m_nMin; } void CalendarWidget::setMinute(int m) { m_nMin = m; disconnect(comboBox_min, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int))); comboBox_min->setCurrentIndex(m); connect(comboBox_min, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int))); } void CalendarWidget::jumpToDateTime(const QDateTime& dt) { setYear(dt.date().year()); setMonth(dt.date().month()); setDay(dt.date().day()); setHour(dt.time().hour()); setMinute(dt.time().minute()); initDate(); changeCurrentSelectDay(); } void CalendarWidget::setDateTimeRange(const QDateTime &min, const QDateTime &max) { if(max setMinimumSize(377, 323); this->setObjectName("widgetCalendar"); verLayoutCalendar = new QVBoxLayout(this); verLayoutCalendar->setContentsMargins(18, 20, 18, 18); // verLayoutCalendar->setSpacing(6); //! [1] 标题行 widgetTitle = new QWidget(this); widgetTitle->setObjectName("widgetTitle"); widgetTitle->setMinimumHeight(32); comboBox_Year = new QComboBox(this); comboBox_Month = new QComboBox(this); comboBox_Hour = new QComboBox(this); label_splite = new QLabel(this); comboBox_min = new QComboBox(this); QStringList monthList; monthListsetContentsMargins(0, 0, 0, 0); horLayoutWeek->setSpacing(0); for (int i = 0; i setText(s_strWeek[i]); labelWeek[i]->setObjectName("labelWeek"); labelWeek[i]->setMinimumHeight(30); labelWeek[i]->setAlignment(Qt::AlignCenter); if ((0 == (i % 7)) || (6 == (i% 7))) { labelWeek[i]->setProperty("weekend", true); labelWeek[i]->setObjectName("labelWeekend"); } horLayoutWeek->addWidget(labelWeek[i]); } verLayoutCalendar->addWidget(widgetWeek); //! [2] //! [3] 主体日期 widgetBody = new QWidget(this); verLayoutCalendar->addWidget(widgetBody, 1); gridLayoutBody = new QGridLayout(widgetBody); gridLayoutBody->setHorizontalSpacing(0); gridLayoutBody->setVerticalSpacing(0); gridLayoutBody->setContentsMargins(0, 0, 0, 0); for (int i = 0; i setObjectName("labelDay"); labelDay[i]->setAlignment(Qt::AlignCenter); labelDay[i]->setText(QString::number(i)); if ((0 == (i % 7)) || (6 == (i% 7))) { labelDay[i]->setProperty("weekend", true); } gridLayoutBody->addWidget(labelDay[i], i / 7, i % 7); connect(labelDay[i], SIGNAL(signalClicked(int,int)), this, SLOT(sltDayClicked(int,int))); } //! [3] //! [4] 底栏行 widget_bottom = new QWidget(this); pushBtn_Rtn = new QPushButton(this); pushBtn_Now = new QPushButton(this); pushBtn_Ok = new QPushButton(this); pushBtn_Rtn->setFixedSize(67, 23); pushBtn_Now->setFixedSize(67, 23); pushBtn_Ok->setFixedSize(67, 23); pushBtn_Rtn->setText(LC_STR("返回今天")); pushBtn_Now->setText(LC_STR("此刻")); pushBtn_Ok->setText(LC_STR("确定")); QHBoxLayout* hBottomLay = new QHBoxLayout(widget_bottom); hBottomLay->setContentsMargins(25, 0, 25, 13); hBottomLay->addWidget(pushBtn_Rtn); hBottomLay->addStretch(1); hBottomLay->addWidget(pushBtn_Now); hBottomLay->addStretch(1); hBottomLay->addWidget(pushBtn_Ok); verLayoutCalendar->addWidget(widget_bottom); connect(pushBtn_Rtn, SIGNAL(clicked()), this, SLOT(slotPushBtnRtn())); connect(pushBtn_Now, SIGNAL(clicked()), this, SLOT(slotPushBtnNow())); connect(pushBtn_Ok, SIGNAL(clicked()), this, SLOT(slotPushBtnOk())); //! [4] } /** * @brief CalendarWidget::initDate 初始化日期 */ void CalendarWidget::initDate() { // 首先判断当前月的第一天是星期几 int nWeek = Date::getFirstDayOfWeek(m_nYear, m_nMonth); int nMonthDays = Date::getMonthDays(m_nYear, m_nMonth); // 上月天数 int nPreMonDays = Date::getMonthDays(1 == m_nMonth ? m_nYear - 1 : m_nYear, 1 == m_nMonth ? 12 : m_nMonth - 1); // 显示上月剩余天数 if (0 == nWeek) { // 显示上月天数 for (int i = 0; i showDay((nPreMonDays - 7 + i + 1), Date::getLunarDate(m_nYear, m_nMonth, nPreMonDays - 7 + i + 1)); labelDay[i]->setColor(PREV_MONTH_DAY); } // 显示下月天数 for (int i = 0; i showDay((i + 1), Date::getLunarDate(m_nYear, m_nMonth, i + 1)); labelDay[nMonthDays + 7 + i]->setColor(NEXT_MONTH_DAY); } } else { for (int i = 0; i showDay((nPreMonDays - nWeek + i + 1), Date::getLunarDate(m_nYear, m_nMonth, (nPreMonDays - nWeek + i + 1))); labelDay[i]->setColor(PREV_MONTH_DAY); } // 显示下月天数 for (int i = (nWeek + nMonthDays); i showDay((i - (nWeek + nMonthDays) + 1), Date::getLunarDate(m_nYear, m_nMonth, (i - (nWeek + nMonthDays) + 1))); labelDay[i]->setColor(NEXT_MONTH_DAY); } } // 显示当前月 int nProperty = 1; int index = 0; for (int i = nWeek; i showDay(i - nWeek + 1, Date::getLunarDate(m_nYear, m_nMonth, i - nWeek + 1)); nProperty = (((0 == (i % 7)) || (6 == (i% 7))) ? WEEKEND_DAY : CURR_MONTH_DAY); labelDay[index]->setColor(nProperty); } // 如果现在显示的是当前月,则设置当前的日期 QDate d = QDate::currentDate(); if(d == QDate(m_nYear, m_nMonth, d.day())) { getDayLabel(m_nYear, m_nMonth, d.day())->setColor(CURRENT_DAY); } } /** * @brief CalendarWidget::sltDayClicked 点击响应 * @param type 类型 0 表示上月 1表示下月 * @param day 当前点击的天数 */ void CalendarWidget::sltDayClicked(int type, int day) { // 上月 if (PREV_MONTH_DAY == type) { sltShowPrevMonth(); } // 下月 else if (NEXT_MONTH_DAY == type) { sltShowNextMonth(); } // 当天/周末/当月天数都显示在右边,并转换成农历 else if ((CURR_MONTH_DAY == type) || (WEEKEND_DAY == type) || (CURRENT_DAY == type)) { // 选中当天 m_nDay = day; emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin))); } // 更改当前选中项 changeCurrentSelectDay(); } /** * @brief CalendarWidget::sltShowPrevMonth 显示上月日期 */ void CalendarWidget::sltShowPrevMonth() { m_nMonth--; if (m_nMonth 12) { m_nMonth = 1; m_nYear++; } setYear(m_nYear); setMonth(m_nMonth); initDate(); // 发送更新信号 emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin))); } void CalendarWidget::sltComboBoxDateChange(int) { if(comboBox_Year->isVisible() && comboBox_Month->isVisible()) { m_nYear = comboBox_Year->currentText().toInt(); m_nMonth = comboBox_Month->currentIndex() + 1; int days = Date::getMonthDays(m_nYear, m_nMonth); if(m_nDay > days) m_nDay = days; initDate(); // 更新当前选中项 changeCurrentSelectDay(); // 发送更新信号 emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin))); } } void CalendarWidget::sltComboBoxTimeChange(int) { if(comboBox_Hour->isVisible() && comboBox_min->isVisible()) { m_nHour = comboBox_Hour->currentIndex(); m_nMin = comboBox_min->currentIndex(); emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin))); } } void CalendarWidget::slotPushBtnRtn() { jumpToDateTime(QDateTime::currentDateTime()); emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin))); } void CalendarWidget::slotPushBtnNow() { slotPushBtnRtn(); close(); } void CalendarWidget::slotPushBtnOk() { close(); }

3. 实现每天的label效果:

/// /// \brief The DayLabel class /// 自定义的日子显示控件 /// class DayLabel : public QLabel { Q_OBJECT public: explicit DayLabel(QWidget *parent = 0); bool getBSelect() const; void setSelected(bool value); void setColor(int type); void showDay(int nDay, QString strLunar); signals: void signalClicked(int ntype, int day); private: QLabel *labelIcon; int m_nDay; bool m_bHover; bool m_bSelect; QString m_strText; protected: void enterEvent(QEvent *e); void leaveEvent(QEvent *e); void mousePressEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void paintEvent(QPaintEvent* e); };

// /// \brief DayLabel::DayLabel /// \param parent #include #include #include DayLabel::DayLabel(QWidget *parent): QLabel(parent) { m_bSelect = false; m_nDay = 0; m_bHover = false; } bool DayLabel::getBSelect() const { return m_bSelect; } void DayLabel::setSelected(bool value) { m_bSelect = value; update(); } void DayLabel::setColor(int type) { // 设置控件属性类型 this->setProperty("type", type); update(); } /** * @brief DayLabel::showDay * @param nDay * @param strLunar * @param type */ void DayLabel::showDay(int nDay, QString strLunar) { m_strText = QString::number(nDay); m_nDay = nDay; #if Has_Lunar // 显示农历 if ("" != strLunar) { m_strText.append("\n"); m_strText.append(strLunar); } #endif } void DayLabel::enterEvent(QEvent *e) { int nProperty = this->property("type").toInt(); if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return; m_bHover = true; update(); QLabel::enterEvent(e); } void DayLabel::leaveEvent(QEvent *e) { int nProperty = this->property("type").toInt(); if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return; m_bHover = false; update(); QLabel::leaveEvent(e); } void DayLabel::mousePressEvent(QMouseEvent *e) { emit signalClicked(this->property("type").toInt(), m_nDay); QLabel::mousePressEvent(e); } void DayLabel::mouseDoubleClickEvent(QMouseEvent *e) { // int nProperty = this->property("type").toInt(); // if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return; QLabel::mouseDoubleClickEvent(e); } void DayLabel::paintEvent(QPaintEvent *e) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); // 不是悬停 if(!m_bHover) { // 选中 if(m_bSelect) { p.setBrush(QBrush(QColor("#117dd9"))); p.setPen(QPen(QColor("#117dd9"), 1)); #if Has_Lunar // 显示农历 p.drawRect(rect()); #else p.drawEllipse(rect().center(), 12, 12); #endif p.setPen(QPen(QColor("#ffffff"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } else { int type = this->property("type").toInt(); // 当前日 if(CURRENT_DAY == type) { p.setPen(QPen(QColor("#117dd9"), 1)); #if Has_Lunar // 显示农历 p.drawRect(rect()); #else p.drawEllipse(rect().center(), 12, 12); #endif p.setPen(QPen(QColor("#cadfff"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } // 其他月 else if ((PREV_MONTH_DAY == type) || (NEXT_MONTH_DAY == type)) { p.setPen(QPen(QColor("#2360bc"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } // 当前月 else if (CURR_MONTH_DAY == type) { p.setPen(QPen(QColor("#cadfff"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } // 周末 else if (WEEKEND_DAY == type) { p.setPen(QPen(QColor("#00caff"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } } } // 悬停的效果 else { p.setBrush(QBrush(QColor("#117dd9"))); p.setPen(QPen(QColor("#117dd9"), 1)); #if Has_Lunar // 显示农历 p.drawRect(rect()); #else p.drawEllipse(rect().center(), 12, 12); #endif p.setPen(QPen(QColor("#ffffff"), 1)); p.drawText(rect(), Qt::AlignCenter, m_strText); } // QLabel::paintEvent(e); }

4. 日历、农历的算法实现:

#define LC_STR QString::fromLocal8Bit class Date : public QObject { Q_OBJECT public: explicit Date(QObject *parent = 0); signals: public slots: public: static quint16 getSpringFestivalDate(int year); static int getFirstDayOfWeek(int year, int month); static int getTotalMonthDays(int year, int month); static int getMonthDays(int year, int month); static bool isLoopYaer(int year); static QString getLunarDate(int year, int month, int day); static QString getLunarMonAndDay(int year, int month, int day); // 计算今年是什么年如 :甲子年 static QString getLunarTime(int year); private: static QString holiday(int month, int day); static QString solarTerms(int year, int month, int day); static QString lunarFestival(int month, int day); };

#define T_D_YAER 1924 // 天干地支开始计算年月 //每年春节对应的公历日期 static const int springFestival[] = { 130,217,206, // 1968,1969,1970 127,215,203,123,211,131,218,207,128,216, // 1971--1980 205,125,213,202,220,209,219,217,206,127, // 1981---1990 215,204,123,210,131,219,207,128,216,205, // 1991--2000 124,212,201,122,209,129,218,207,126,214, // 2001--2010 203,123,210,131,219,208,128,216,205,125, // 2011--2020 //2011--2020 212,201,122,210,129,217,206,126,213,203, // 2021--2030 123,211,131,219,208,128,215,204,124,212 // 2031--2040 }; //16--18位表示闰几月,0--12位表示农历每月的数据,高位表示1月,低位表示12月(农历闰月就会多一个月) static const int nLunarData[] = { 461653,1386,2413, // 1968,1969,1970 330077,1197,2637,268877,3365,531109,2900,2922,398042,2395, // 1971--1980 1179,267415,2635,661067,1701,1748,398772,2742,2391,330031, // 1981---1990 1175,1611,200010,3749,527717,1452,2742,332397,2350,3222, // 1991--2000 268949,3402,3493,133973,1386,464219,605,2349,334123,2709, // 2001--2010 2890,267946,2773,592565,1210,2651,395863,1323,2707,265877, // 2011--2020 1706,2773,133557,1206,398510,2638,3366,335142,3411,1450, // 2021 -- 2030 200042,2413,723293,1197,2637,399947,3365,3410,334676,2906 // 2031 -- 2040 }; static const int chineseTwentyFourData[] = { 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 1970 0x96,0xB4,0x96,0xA6,0x97,0x97,0x78,0x79,0x79,0x69,0x78,0x77, // 1971 0x96,0xA4,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 1972 0xA5,0xB5,0x96,0xA5,0xA6,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 1973 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 1974 0x96,0xB4,0x96,0xA6,0x97,0x97,0x78,0x79,0x78,0x69,0x78,0x77, // 1975 0x96,0xA4,0xA5,0xB5,0xA6,0xA6,0x88,0x89,0x88,0x78,0x87,0x87, // 1976 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 1977 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x78,0x87, // 1978 0x96,0xB4,0x96,0xA6,0x96,0x97,0x78,0x79,0x78,0x69,0x78,0x77, // 1979 0x96,0xA4,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 1980 0xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x77,0x87, // 1981 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87, // 1982 0x95,0xB4,0x96,0xA5,0x96,0x97,0x78,0x79,0x78,0x69,0x78,0x77, // 1983 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87, // 1984 0xA5,0xB4,0xA6,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 1985 0xA5,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87, // 1986 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x79,0x78,0x69,0x78,0x87, // 1987 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 1988 0xA5,0xB4,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87, // 1989 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87, // 1990 0x95,0xB4,0x96,0xA5,0x86,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 1991 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 1992 0xA5,0xB3,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87, // 1993 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 1994 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x76,0x78,0x69,0x78,0x87, // 1995 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 1996 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 1997 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 1998 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 1999 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2000 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 2001 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 2002 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 2003 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2004 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 2005 0xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 2006 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87, // 2007 0x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x87,0x78,0x87,0x86, // 2008 0xA5,0xB3,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 2009 0xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 2010 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x78,0x87, // 2011 0x96,0xB4,0xA5,0xB5,0xA5,0xA6,0x87,0x88,0x87,0x78,0x87,0x86, // 2012 0xA5,0xB3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87, // 2013 0xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 2014 0x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87, // 2015 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x87,0x88,0x87,0x78,0x87,0x86, // 2016 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87, // 2017 0xA5,0xB4,0xA6,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 2018 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87, // 2019 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x86, // 2020 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2021 0xA5,0xB4,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87, // 2022 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87, // 2023 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96, // 2024 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2025 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 2026 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 2027 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96, // 2028 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2029 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87, // 2030 0xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87, // 2031 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96, // 2032 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x86, // 2033 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x78,0x88,0x78,0x87,0x87, // 2034 0xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87, // 2035 0x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96, // 2036 0xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86, // 2037 0xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87 // 2038 }; static const QString dayName[] = { LC_STR("*"), LC_STR("初一"), LC_STR("初二"), LC_STR("初三"), LC_STR("初四"), LC_STR("初五"), LC_STR("初六"), LC_STR("初七"), LC_STR("初八"), LC_STR("初九"), LC_STR("初十"), LC_STR("十一"), LC_STR("十二"), LC_STR("十三"), LC_STR("十四"), LC_STR("十五"), LC_STR("十六"), LC_STR("十七"), LC_STR("十八"), LC_STR("十九"), LC_STR("二十"), LC_STR("廿一"), LC_STR("廿二"), LC_STR("廿三"), LC_STR("廿四"), LC_STR("廿五"), LC_STR("廿六"), LC_STR("廿七"), LC_STR("廿八"), LC_STR("廿九"), LC_STR("三十") }; /*农历月份名*/ static const QString monName[] = { LC_STR("*"), LC_STR("正月"), LC_STR("二月"), LC_STR("三月"), LC_STR("四月"), LC_STR("五月"), LC_STR("六月"), LC_STR("七月"), LC_STR("八月"), LC_STR("九月"), LC_STR("十月"), LC_STR("冬月"), LC_STR("腊月") }; // 24节气 static const QString solarTerm[] = { LC_STR("小寒"), LC_STR("大寒"), LC_STR("立春"), LC_STR("雨水"), LC_STR("惊蛰"), LC_STR("春分"), LC_STR("清明"), LC_STR("谷雨"), LC_STR("立夏"), LC_STR("小满"), LC_STR("芒种"), LC_STR("夏至"), LC_STR("小暑"), LC_STR("大暑"), LC_STR("立秋"), LC_STR("处暑"), LC_STR("白露"), LC_STR("秋分"), LC_STR("寒露"), LC_STR("霜降"), LC_STR("立冬"), LC_STR("小雪"), LC_STR("大雪"), LC_STR("冬至") }; // 天干算法 static const QString strTiangan[] = { LC_STR("甲"), LC_STR("乙"), LC_STR("丙"), LC_STR("丁"), LC_STR("戊"), LC_STR("己"), LC_STR("庚"), LC_STR("辛"), LC_STR("壬"), LC_STR("癸"), }; // 动物属性 static const QString strAnimal[] = { LC_STR("鼠"), LC_STR("牛"), LC_STR("虎"), LC_STR("兔"), LC_STR("龙"), LC_STR("蛇"), LC_STR("马"), LC_STR("羊"), LC_STR("猴"), LC_STR("鸡"), LC_STR("狗"), LC_STR("猪"), }; // 地址算法 static const QString strDizhi[] = { LC_STR("子"), LC_STR("丑"), LC_STR("寅"), LC_STR("卯"), LC_STR("辰"), LC_STR("巳"), LC_STR("午"), LC_STR("未"), LC_STR("申"), LC_STR("酉"), LC_STR("戌"), LC_STR("亥"), }; /*公历每月前面的天数*/ int monthAdd[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; Date::Date(QObject *parent) : QObject(parent) { } /** * @brief Date::getSpringFestivalMonth 获取当年春节是几月几日 * @param year * @return */ quint16 Date::getSpringFestivalDate(int year) { int nTemp = year - 1968; int springFestivalMonth = springFestival[nTemp] / 100; int springFestivalDay = springFestival[nTemp] % 100; qDebug() > n; nBit = nBit % 2; if (nTheDate (nLunarData[nMonTemp] / 65536) + 1) month = month - 1; } // 显示装换的农历 // only day == 1 ,return month name if (1 == day) { if (month T_D_YAER) { ntemp = year - T_D_YAER; strTime.append(strTiangan[ntemp % 10]); strTime.append(strDizhi[ntemp % 12]); strTime.append(strAnimal[ntemp % 12]); strTime.append(LC_STR("年")); } return strTime; } /** * @brief Date::holiday 公历假日 * @param month * @param day * @return */ QString Date::holiday(int month, int day) { int temp = (month 15) { dayTemp = day - 15; if((chineseTwentyFourData[index] & 0x0f) == dayTemp) return solarTerm[2 * (month - 1) + 1]; } return ""; } /** * @brief Date::lunarFestival 农历春节节日 * @param month * @param day * @return 节日 */ QString Date::lunarFestival(int month, int day) { int temp = (month


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有