当前位置:网站首页>QT custom implemented calendar control

QT custom implemented calendar control

2022-06-25 23:34:00 The struggle history of polar bear

QDateTimeEdit or  QCalendarWidget It is difficult to achieve when beautifying the interface , And many effects cannot be customized , For example, the effect of lighting outside the calendar background , So you can customize a log , All the effects can be customized and realized . Great .

notes : Although this blog is original , But the custom implementation of the control is a reference Blogger lynnhua_ A piece of Qt Make a calendar with the lunar calendar To achieve the effect of , Source address :https://blog.csdn.net/nigoole/article/details/51320239.

Let me show you the effect after implementation .


1. First, I customized a button , Inherited from QPushButton, And beautify , Make it look like an input field .

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. Click the button again , The calendar interface pops up

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(" Sunday "), LC_STR(" Monday "), LC_STR(" Tuesday "),
    LC_STR(" Wednesday "), LC_STR(" Thursday "), LC_STR(" Friday "),
    LC_STR(" Saturday "),
};
CalendarWidget::CalendarWidget(QWidget *parent, Qt::WindowFlags f)
    : QWidget(parent, f)
{
  
    //  Get the current date 
    m_nYear  = QDate::currentDate().year();
    m_nMonth = QDate::currentDate().month();
    m_nDay = QDate::currentDate().day();
    m_pCrtSelect = NULL;
    //   Set the default date range 
    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(); i<= d2.year(); i++)
    {
  
        comboBox_Year->addItem(QString::number(i));
    }
}
DayLabel *CalendarWidget::getDayLabel(int y, int m, int d)
{
  
    int nWeek  = Date::getFirstDayOfWeek(y, m);
	nWeek = (0 == nWeek ? 7 : nWeek);
    //  Displays the current number of days 
    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 <= min)
        return;
    m_minDt = min; m_maxDt = max;
}
void CalendarWidget::dateTimeRange(QDateTime &min, QDateTime &max)
{
  
    min = m_minDt; max = m_maxDt;
}
/**
 * @brief CalendarWidget::initWidget  Initialization interface 
 */
void CalendarWidget::initWidget()
{
  
    this->setMinimumSize(377, 323);
    this->setObjectName("widgetCalendar");
    verLayoutCalendar = new QVBoxLayout(this);
    verLayoutCalendar->setContentsMargins(18, 20, 18, 18);
//    verLayoutCalendar->setSpacing(6);
    //! [1]  Title Line 
    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;
    monthList<<LC_STR(" January ")<<LC_STR(" February ")<<LC_STR(" March ")<<LC_STR(" April ")<<LC_STR(" May ")<<LC_STR(" June ")
             <<LC_STR(" July ")<<LC_STR(" August ")<<LC_STR(" September ")<<LC_STR(" October ")<<LC_STR(" November ")<<LC_STR(" December ");
    comboBox_Month->addItems(monthList);
	label_splite->setText(LC_STR(":"));
	label_splite->setMinimumWidth(4);
	comboBox_Hour->clear();
	for (int i = 0; i < 24; ++i)
		comboBox_Hour->addItem(QString::asprintf("%02d", i));
	comboBox_min->clear();
	for (int i = 0; i < 60; ++i)
		comboBox_min->addItem(QString::asprintf("%02d", i));
    QHBoxLayout *HTopLayout = new QHBoxLayout(widgetTitle);
    HTopLayout->setContentsMargins(14, 0, 14, 0);
    HTopLayout->setSpacing(0);
    HTopLayout->addWidget(comboBox_Year);
    HTopLayout->addStretch(1);
    HTopLayout->addWidget(comboBox_Month);
	HTopLayout->addStretch(1);
	HTopLayout->addWidget(comboBox_Hour);
	HTopLayout->addWidget(label_splite);
	HTopLayout->addWidget(comboBox_min);
    verLayoutCalendar->addWidget(widgetTitle);
    comboBox_Year->setObjectName("comboBox_Year");
    comboBox_Month->setObjectName("comboBox_Month");
	label_splite->setObjectName("label_splite");
	comboBox_Year->setItemDelegate(new QStyledItemDelegate());
	comboBox_Month->setItemDelegate(new QStyledItemDelegate());
	comboBox_Hour->setItemDelegate(new QStyledItemDelegate());
	comboBox_min->setItemDelegate(new QStyledItemDelegate());
    connect(comboBox_Year, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int)));
    connect(comboBox_Month, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxDateChange(int)));
	connect(comboBox_Hour, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int)));
	connect(comboBox_min, SIGNAL(currentIndexChanged(int)), this, SLOT(sltComboBoxTimeChange(int)));
    //! [1]
    //! [2]  Week line 
    widgetWeek = new QWidget(this);
    widgetWeek->setObjectName("widgetWeek");
    horLayoutWeek = new QHBoxLayout(widgetWeek);
    horLayoutWeek->setContentsMargins(0, 0, 0, 0);
    horLayoutWeek->setSpacing(0);
    for (int i = 0; i < Week; i++) {
  
        labelWeek[i] = new QLabel(widgetWeek);
        labelWeek[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]  Subject date 
    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 < 42; i++) {
  
        labelDay[i] = new DayLabel(widgetBody);
        labelDay[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]  Bottom column row 
    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(" Back to today "));
    pushBtn_Now->setText(LC_STR(" At the moment "));
    pushBtn_Ok->setText(LC_STR(" determine "));
    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  Initialization date 
 */
void CalendarWidget::initDate()
{
  
    //  First, judge the day of the week on the first day of the current month 
    int nWeek  = Date::getFirstDayOfWeek(m_nYear, m_nMonth);
    int nMonthDays = Date::getMonthDays(m_nYear, m_nMonth);
    //  The number of days last month 
    int nPreMonDays = Date::getMonthDays(1 == m_nMonth ? m_nYear - 1 : m_nYear, 1 == m_nMonth ? 12 : m_nMonth - 1);
    //  Display the remaining days of last month 
    if (0 == nWeek) {
  
        //  Display last month days 
        for (int i = 0; i < 7; i++) {
  
            labelDay[i]->showDay((nPreMonDays - 7 + i + 1), Date::getLunarDate(m_nYear, m_nMonth, nPreMonDays - 7 + i + 1));
            labelDay[i]->setColor(PREV_MONTH_DAY);
        }
        //  Displays the number of days in the next month 
        for (int i = 0; i < (42 - nMonthDays - 7); i++) {
  
            labelDay[nMonthDays + 7 + 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 < nWeek; i++) {
  
            labelDay[i]->showDay((nPreMonDays - nWeek + i + 1), Date::getLunarDate(m_nYear, m_nMonth, (nPreMonDays - nWeek + i + 1)));
            labelDay[i]->setColor(PREV_MONTH_DAY);
        }
        //  Displays the number of days in the next month 
        for (int i = (nWeek + nMonthDays); i < 42; i++) {
  
            labelDay[i]->showDay((i - (nWeek + nMonthDays) + 1), Date::getLunarDate(m_nYear, m_nMonth, (i - (nWeek + nMonthDays) + 1)));
            labelDay[i]->setColor(NEXT_MONTH_DAY);
        }
    }
    //  Displays the current month 
    int nProperty = 1;
    int index = 0;
    for (int i = nWeek; i < (nMonthDays + nWeek); i++) {
  
        index = (0 == nWeek ? (i + 7) : i);
        labelDay[index]->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);
    }
    //   If the current month is displayed , Set the current date 
    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  Click response 
 * @param type   type  0  Last month  1 Next month 
 * @param day   The number of days currently clicked 
 */
void CalendarWidget::sltDayClicked(int type, int day)
{
  
    //  Last month, 
    if (PREV_MONTH_DAY == type) {
  
        sltShowPrevMonth();
    }
    //  Next month 
    else if (NEXT_MONTH_DAY == type) {
  
        sltShowNextMonth();
    }
    //  same day / Over the weekend / The days of the month are displayed on the right , And convert it into the lunar calendar 
    else if ((CURR_MONTH_DAY == type)
             || (WEEKEND_DAY == type)
             || (CURRENT_DAY == type)) {
  
        //  Select the day 
        m_nDay = day;
        emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin)));
    }
    //   Change the currently selected item 
    changeCurrentSelectDay();
}
/**
 * @brief CalendarWidget::sltShowPrevMonth  Display last month date 
 */
void CalendarWidget::sltShowPrevMonth()
{
  
    m_nMonth--;
    if (m_nMonth < 1) {
  
        m_nMonth = 12;
        m_nYear--;
    }
    setYear(m_nYear);
    setMonth(m_nMonth);
    initDate();
    //  Send update signal 
    emit dayClicked(QDateTime(QDate(m_nYear, m_nMonth, m_nDay), QTime(m_nHour, m_nMin)));
}
/**
 * @brief CalendarWidget::sltShowNextMonth  Display the next month's date 
 */
void CalendarWidget::sltShowNextMonth()
{
  
    m_nMonth++;
    if (m_nMonth > 12) {
  
        m_nMonth = 1;
        m_nYear++;
    }
    setYear(m_nYear);
    setMonth(m_nMonth);
    initDate();
    //  Send update signal 
    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();
        //   Update the currently selected item 
        changeCurrentSelectDay();
        //  Send update signal 
        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. Realize the daily label effect :

///
/// \brief The DayLabel class
///  Custom day display control 
///
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 <QMouseEvent>
#include <QEvent>
#include <QPixmap>
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)
{
  
    //  Set control property 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    //   Show the lunar calendar 
    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);
    //   Not hovering 
    if(!m_bHover)
    {
  
        //   Choose 
        if(m_bSelect)
        {
  
            p.setBrush(QBrush(QColor("#117dd9")));
            p.setPen(QPen(QColor("#117dd9"), 1));
#if Has_Lunar    //   Show the lunar calendar 
			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();
            //   Current day 
            if(CURRENT_DAY == type)
            {
  
				p.setPen(QPen(QColor("#117dd9"), 1));
#if Has_Lunar    //   Show the lunar calendar 
				p.drawRect(rect());
#else
                p.drawEllipse(rect().center(), 12, 12);
#endif
				p.setPen(QPen(QColor("#cadfff"), 1));
                p.drawText(rect(), Qt::AlignCenter, m_strText);
            }
            //  Other months 
            else if ((PREV_MONTH_DAY == type) || (NEXT_MONTH_DAY == type)) {
  
                p.setPen(QPen(QColor("#2360bc"), 1));
                p.drawText(rect(), Qt::AlignCenter, m_strText);
            }
            //  The current month 
            else if (CURR_MONTH_DAY == type) {
  
                p.setPen(QPen(QColor("#cadfff"), 1));
                p.drawText(rect(), Qt::AlignCenter, m_strText);
            }
            //  Over the weekend 
            else if (WEEKEND_DAY == type) {
  
                p.setPen(QPen(QColor("#00caff"), 1));
                p.drawText(rect(), Qt::AlignCenter, m_strText);
            }
        }
    }
    //   Hover effect 
    else
    {
  
		p.setBrush(QBrush(QColor("#117dd9")));
		p.setPen(QPen(QColor("#117dd9"), 1));
#if Has_Lunar    //   Show the lunar calendar 
		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. The calendar 、 Algorithm implementation of lunar calendar :

#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);
    //  Calculate what year this year is  : Jiazi year 
    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 //   The heavenly stems and Earthly Branches began to calculate the month and year 
// The Gregorian calendar date corresponding to the Spring Festival of each year 
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 Bits indicate leap months ,0--12 Bits represent the monthly data of the lunar calendar , High bit representation 1 month , Low order representation 12 month ( The leap month of the lunar calendar will be one more month )
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(" The new moon "), LC_STR(" Lunar calendar "), LC_STR(" grade "), LC_STR(" fourth day of a lunar month "), LC_STR(" The fifth day "),
    LC_STR(" Sixth day "), LC_STR(" seventh day of a lunar month "), LC_STR(" Eighth day of the first year "), LC_STR(" ninth day of a lunar month "), LC_STR(" tenth day of a lunar month "),
    LC_STR(" 11、 ... and "), LC_STR(" Twelve "), LC_STR(" 13、 ... and "), LC_STR(" fourteen "), LC_STR(" 15、 ... and "),
    LC_STR(" sixteen "), LC_STR(" seventeen "), LC_STR(" eighteen "), LC_STR(" nineteen "), LC_STR(" twenty "),
    LC_STR(" 21 "), LC_STR(" 22 "), LC_STR(" Twenty three "), LC_STR(" Twenty four "), LC_STR(" Twenty five "),
    LC_STR(" 26 "), LC_STR(" 27 "), LC_STR(" 28 "), LC_STR(" 29 "), LC_STR(" thirty ")
};
/* Lunar month name */
static const QString monName[] = {
  
    LC_STR("*"),
    LC_STR(" In the first month "), LC_STR(" February "), LC_STR(" March "), LC_STR(" April "),
    LC_STR(" May "), LC_STR(" June "), LC_STR(" July "), LC_STR(" August "),
    LC_STR(" September "), LC_STR(" October "), LC_STR(" Winter moon "), LC_STR(" December ")
};
// 24 Solar terms 
static const QString solarTerm[] = {
  
    LC_STR(" slight cold "), LC_STR(" Severe cold "), LC_STR(" Beginning of spring "), LC_STR(" Rain "), LC_STR(" The Waking of Insects "), LC_STR(" Vernal equinox "), LC_STR(" Qingming "), LC_STR(" Grain Rain "),
    LC_STR(" Beginning of summer "), LC_STR(" grain full "), LC_STR(" Grain in the air "), LC_STR(" the summer solstice "), LC_STR(" Xiaoshu "), LC_STR(" Great heat "), LC_STR(" The beginning of autumn "), LC_STR(" In the heat "),
    LC_STR(" White Dew "), LC_STR(" the autumnal equinox "), LC_STR(" Cold dew "), LC_STR(" First Frost "), LC_STR(" Primordial winter "), LC_STR(" Light snow "), LC_STR(" heavy snow "), LC_STR(" Winter solstice ")
};
//  Heavenly stems algorithm 
static const QString strTiangan[] = {
  
    LC_STR(" nail "), LC_STR(" B "), LC_STR(" C "), LC_STR(" Ding "), LC_STR(" E "),
    LC_STR(" Oneself "), LC_STR(" Geng "), LC_STR(" simba "), LC_STR(" Ren "), LC_STR(" Dec. "),
};
//  Animal properties 
static const QString strAnimal[] = {
  
    LC_STR(" rat "), LC_STR(" cattle "), LC_STR(" The tiger "), LC_STR(" rabbit "), LC_STR(" dragon "), LC_STR(" The snake "),
    LC_STR(" Horse "), LC_STR(" sheep "), LC_STR(" Monkey "), LC_STR(" chicken "), LC_STR(" Dog "), LC_STR(" The pig "),
};
//  Address algorithm 
static const QString strDizhi[] = {
  
    LC_STR(" Son "), LC_STR(" ugly "), LC_STR(" Yin "), LC_STR(" Mao "), LC_STR(" Chen" "), LC_STR(" Already "),
    LC_STR(" Noon "), LC_STR(" not "), LC_STR(" Shen "), LC_STR(" Unitary "), LC_STR(" Xu "), LC_STR(" Hai "),
};
/* The first days of each calendar month */
int monthAdd[] = {
  
    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
Date::Date(QObject *parent) : QObject(parent)
{
  
}
/**
 * @brief Date::getSpringFestivalMonth  Get the date of the Spring Festival 
 * @param year
 * @return
 */
quint16 Date::getSpringFestivalDate(int year)
{
  
    int nTemp = year - 1968;
    int springFestivalMonth = springFestival[nTemp] / 100;
    int springFestivalDay = springFestival[nTemp] % 100;
    qDebug() << springFestivalMonth << springFestivalDay;
    return (springFestivalMonth << 8) | springFestivalDay;
}
int Date::getFirstDayOfWeek(int year, int month)
{
  
    int week = 0;
    //  Get the year 1 month 1 What day is the day of the week 
    week = (year + (year- 1) / 4 -(year - 1) / 100 + (year - 1) / 400) % 7;
    week += getTotalMonthDays(year, month);
    return week % 7;
}
int Date::getTotalMonthDays(int year, int month)
{
  
    int nDays = 0;
    int nLoopDay = isLoopYaer(year) ? 1 : 0;
    switch (month) {
  
    case  1: nDays =   0;            break;
    case  2: nDays =  31;            break;
    case  3: nDays =  59 + nLoopDay; break;
    case  4: nDays =  90 + nLoopDay; break;
    case  5: nDays = 120 + nLoopDay; break;
    case  6: nDays = 151 + nLoopDay; break;
    case  7: nDays = 181 + nLoopDay; break;
    case  8: nDays = 212 + nLoopDay; break;
    case  9: nDays = 243 + nLoopDay; break;
    case 10: nDays = 273 + nLoopDay; break;
    case 11: nDays = 304 + nLoopDay; break;
    case 12: nDays = 334 + nLoopDay; break;
    default: nDays = 0; break;
    }
    return nDays;
}
int Date::getMonthDays(int year, int month)
{
  
    int nDays = 0;
    int nLoopDay = isLoopYaer(year) ? 1 : 0;
    switch (month) {
  
    case  1: nDays = 31;            break;
    case  2: nDays = 28 + nLoopDay; break;
    case  3: nDays = 31;            break;
    case  4: nDays = 30;            break;
    case  5: nDays = 31;            break;
    case  6: nDays = 30;            break;
    case  7: nDays = 31;            break;
    case  8: nDays = 31;            break;
    case  9: nDays = 30;            break;
    case 10: nDays = 31;            break;
    case 11: nDays = 30;            break;
    case 12: nDays = 31;            break;
    default: nDays = 30;            break;
    }
    return nDays;
}
bool Date::isLoopYaer(int year)
{
  
    return (((0 == (year % 4)) && (0 != (year % 100))) || (0 == (year % 400)));
}
/**
 * @brief Date::getLunarDate  Calculate the lunar calendar 
 * @param year   year 
 * @param month  month 
 * @param day  Japan 
 * @return
 */
QString Date::getLunarDate (int year, int month, int day){
  
    int nTheDate,nIsEnd,nMonTemp,k,n,nBit;
    //  Get the Gregorian calendar Festival first 
    QString strDate = holiday(month, day);
    //  Calculation 24 Solar terms 
    QString strSolarTerms = solarTerms(year, month, day);
    /* Now calculate the lunar calendar : Get the Gregorian calendar date of the Spring Festival of that year ( such as :2015 Spring Festival in (2 month 19 Japan )),
             Take this as the dividing point ,2.19 The previous lunar calendar is 2014 Lunar calendar ( use 2014 Calculated according to the lunar calendar data ),
            2.19 And subsequent dates , The lunar calendar is 2015 Lunar calendar ( use 2015 Calculated according to the lunar calendar data ).*/
    nMonTemp = year - 1968;
    int springFestivalMonth = springFestival[nMonTemp] / 100;
    int springFestivalDaty = springFestival[nMonTemp] % 100;
    if(month < springFestivalMonth )
    {
  
        nMonTemp--;
        nTheDate = 365 * 1 + day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
        if((!(year % 4)) && (month > 2))
            nTheDate = nTheDate + 1;
        if((!((year - 1) % 4)))
            nTheDate = nTheDate + 1;
    }
    else if (month == springFestivalMonth)
    {
  
        if (day < springFestivalDaty) {
  
            nMonTemp--;
            nTheDate = 365 * 1 + day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
            if((!(year % 4)) && (month > 2))
                nTheDate = nTheDate + 1;
            if((!((year-1) % 4)))
                nTheDate = nTheDate + 1;
        }
        else {
  
            nTheDate = day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
            if((!(year % 4)) && (month > 2))
                nTheDate = nTheDate + 1;
        }
    }else{
  
        nTheDate = day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
        if((!(year % 4)) && (month > 2))
            nTheDate = nTheDate + 1;
    }
    /*-- Calculate the lunar calendar days 、 Branches of the earth 、 month 、 Japan ---*/
    nIsEnd = 0;
    while(nIsEnd != 1)  {
  
        if(nLunarData[nMonTemp] < 4095)
            k = 11;
        else
            k = 12;
        n = k;
        while(n >= 0)   {
  
            //  obtain wNongliData(m) Of the n A binary value 
            nBit = nLunarData[nMonTemp];
            nBit = nBit >> n;
            nBit = nBit % 2;
            if (nTheDate <= (29 + nBit))    {
  
                nIsEnd = 1;
                break;
            }
            nTheDate = nTheDate - 29 - nBit;
            n = n - 1;
        }
        if(nIsEnd)
            break;
        nMonTemp = nMonTemp + 1;
    }
    //  The date of the lunar calendar 
    year = 1969 + nMonTemp -1;
    month = k - n + 1;
    day = nTheDate;
    if (k == 12)  {
  
        if (month == (nLunarData[nMonTemp] / 65536) + 1)
            month = 1 - month;
        else if (month > (nLunarData[nMonTemp] / 65536) + 1)
            month = month - 1;
    }
    //  Display the lunar calendar for installation and replacement 
    // only day == 1 ,return month name
    if (1 == day) {
  
        if(month < 1){
  
            strDate = " Leap " + monName[month * -1];
            return strDate;
        }
        //  The Gregorian Festival 
        if ("" != strDate) return strDate;
        //  Calculate the lunar holidays 
        strDate = lunarFestival(month, day);
        //  If there is a festival , Direct display 
        if ("" == strDate) {
  
            //  If the day is not 24 Solar terms , Display the lunar calendar day 
            strDate = strSolarTerms;
            if ("" == strDate) {
  
                strDate = monName[month];
            }
        }
    } else {
  
        //  The Gregorian Festival 
        if ("" != strDate) return strDate;
        //  Calculate the lunar holidays 
        strDate = lunarFestival(month, day);
        //  If there is a festival , Direct display 
        if ("" == strDate) {
  
            //  If the day is not 24 Solar terms , Display the lunar calendar day 
            strDate = strSolarTerms;
            if ("" == strDate) {
  
                strDate = dayName[day];
            }
        }
    }
    return strDate;
}
/**
 * @brief Date::getLunarMonAndDay  Lunar calendar display when responding to click 
 * @param year
 * @param month
 * @param day
 * @return
 */
QString Date::getLunarMonAndDay(int year, int month, int day)
{
  
    int nTheDate, nIsEnd, nMonTemp, k, n, nBit;
    QString strDate = "";
    /* Now calculate the lunar calendar : Get the Gregorian calendar date of the Spring Festival of that year ( such as :2015 Spring Festival in (2 month 19 Japan )),
             Take this as the dividing point ,2.19 The previous lunar calendar is 2014 Lunar calendar ( use 2014 Calculated according to the lunar calendar data ),
            2.19 And subsequent dates , The lunar calendar is 2015 Lunar calendar ( use 2015 Calculated according to the lunar calendar data ).*/
    nMonTemp = year - 1968;
    int springFestivalMonth = springFestival[nMonTemp] / 100;
    int springFestivalDaty = springFestival[nMonTemp] % 100;
    if(month < springFestivalMonth )
    {
  
        nMonTemp--;
        nTheDate = 365 * 1 + day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
        if((!(year % 4)) && (month > 2))
            nTheDate = nTheDate + 1;
        if((!((year - 1) % 4)))
            nTheDate = nTheDate + 1;
    }
    else if (month == springFestivalMonth)
    {
  
        if (day < springFestivalDaty) {
  
            nMonTemp--;
            nTheDate = 365 * 1 + day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
            if((!(year % 4)) && (month > 2))
                nTheDate = nTheDate + 1;
            if((!((year-1) % 4)))
                nTheDate = nTheDate + 1;
        }
        else {
  
            nTheDate = day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
            if((!(year % 4)) && (month > 2))
                nTheDate = nTheDate + 1;
        }
    }else{
  
        nTheDate = day + monthAdd[month - 1] - 31 * ((springFestival[nMonTemp] / 100) - 1) - springFestival[nMonTemp] % 100 + 1;
        if((!(year % 4)) && (month > 2))
            nTheDate = nTheDate + 1;
    }
    /*-- Calculate the lunar calendar days 、 Branches of the earth 、 month 、 Japan ---*/
    nIsEnd = 0;
    while(nIsEnd != 1)  {
  
        if(nLunarData[nMonTemp] < 4095)
            k = 11;
        else
            k = 12;
        n = k;
        while(n >= 0)   {
  
            //  obtain wNongliData(m) Of the n A binary value 
            nBit = nLunarData[nMonTemp];
            nBit = nBit >> n;
            nBit = nBit % 2;
            if (nTheDate <= (29 + nBit))    {
  
                nIsEnd = 1;
                break;
            }
            nTheDate = nTheDate - 29 - nBit;
            n = n - 1;
        }
        if(nIsEnd)
            break;
        nMonTemp = nMonTemp + 1;
    }
    //  The date of the lunar calendar 
    year = 1969 + nMonTemp -1;
    month = k - n + 1;
    day = nTheDate;
    if (k == 12)  {
  
        if (month == (nLunarData[nMonTemp] / 65536) + 1)
            month = 1 - month;
        else if (month > (nLunarData[nMonTemp] / 65536) + 1)
            month = month - 1;
    }
    //  Display the lunar calendar for installation and replacement 
    // only day == 1 ,return month name
    if (1 == day) {
  
        if (month < 1){
  
            strDate = LC_STR(" Leap ") + monName[month * -1];
            return strDate;
        }
        strDate = monName[month];
    } else {
  
        strDate = monName[month]+ dayName[day];
    }
    return strDate;
}
/**
 * @brief Date::getLunarTime   Calculate what year this year is  : Jiazi year 
 * @param year
 * @return
 */
QString Date::getLunarTime(int year)
{
  
    int ntemp = 0;
    //  The lunar hour 
    QString strTime = "";
    if (year > 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(" year "));
    }
    return strTime;
}
/**
 * @brief Date::holiday  Gregorian holidays 
 * @param month
 * @param day
 * @return
 */
QString Date::holiday(int month, int day)
{
  
    int temp = (month << 8) | day;
    QString strHoliday = "";
    switch (temp) {
  
    case 0x0101: strHoliday = LC_STR(" New year's Day ");  break;
    case 0x020E: strHoliday = LC_STR(" Valentine's Day "); break;
    case 0x0308: strHoliday = LC_STR(" Women's Day "); break;
    case 0x0401: strHoliday = LC_STR(" April Fools ' Day "); break;
    case 0x0501: strHoliday = LC_STR(" labor day "); break;
    case 0x0504: strHoliday = LC_STR(" Youth Day "); break;
    case 0x0601: strHoliday = LC_STR(" Children's Day "); break;
    case 0x0701: strHoliday = LC_STR(" Party building day "); break;
    case 0x0801: strHoliday = LC_STR(" Army Day "); break;
    case 0x090A: strHoliday = LC_STR(" Teachers ' Day "); break;
    case 0x0A01: strHoliday = LC_STR(" National Day "); break;
    case 0x0C18: strHoliday = LC_STR(" Christmas "); break;
    default: break;
    }
    return strHoliday;
}
/**
 * @brief Date::chineseTwentyFourDay  Calculation 24 Solar terms 
 * @param year
 * @param month
 * @param day
 * @return
 */
QString Date::solarTerms(int year, int month, int day){
  
    int dayTemp = 0;
    int index = (year - 1970) * 12 + month - 1;
    if (day < 15) {
  
        dayTemp = 15 - day;
        if((chineseTwentyFourData[index] >> 4) == dayTemp)
            return solarTerm[2 * (month - 1)];
        else
            return "";
    } else if (day > 15) {
  
        dayTemp = day - 15;
        if((chineseTwentyFourData[index] & 0x0f) == dayTemp)
            return solarTerm[2 * (month - 1) + 1];
    }
    return "";
}
/**
 * @brief Date::lunarFestival  Chinese New Year Festival 
 * @param month
 * @param day
 * @return  festival 
 */
QString Date::lunarFestival(int month, int day) {
  
    int temp = (month << 8) | day;
    QString strFestival = "";
    switch (temp) {
  
    case 0x0101: strFestival = LC_STR(" Spring Festival ");  break;
    case 0x010F: strFestival = LC_STR(" Lantern Festival "); break;
    case 0x0202: strFestival = LC_STR(" The dragon head "); break;
    case 0x0505: strFestival = LC_STR(" The Dragon Boat Festival "); break;
    case 0x0707: strFestival = LC_STR(" Tanabata Festival "); break;
    case 0x080F: strFestival = LC_STR(" Mid-Autumn Festival "); break;
    case 0x0909: strFestival = LC_STR(" Double Ninth Festival "); break;
    case 0x0C08: strFestival = LC_STR(" Laba Festival "); break;
    default: break;
    }
    return strFestival;
}


remarks : Part of the code uses the author :lynnhua_ Code for , If there is any infringement , Please contact to delete .

Attach the source download address :https://download.csdn.net/download/chenxipu123/10449527

You are welcome to point out your shortcomings .

原网站

版权声明
本文为[The struggle history of polar bear]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206252013020262.html