网上农历算法很多,大部分都是比较准的,但是在Qt里面很少有朋友整理和共享出来,在此,花一点时间整理下资料和想法,顺便或许也能帮助一些新手朋友!

首先讲讲设计思路吧,没有采用系统自带的QCalendarWidget,而是通过42个QLabel拼凑出来的一个界面,之所以采用这种拼凑的方法是方便管理样式,话不多说了上图和代码吧:

先来界面布局代码吧:

#ifndef CALENDARWIDGET_H
#define CALENDARWIDGET_H#include <QWidget>
#include <QLabel>QT_BEGIN_NAMESPACE
class QPushButton;
class QComboBox;
class QGroupBox;
class QLineEdit;
class QDate;
class QGridLayout;
class QHBoxLayout;
class QVBoxLayout;class Event;
class DataBase;
QT_END_NAMESPACEtypedef enum {Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Week
} E_WEEK;typedef enum {PREV_MONTH_DAY,     // 上月剩余天数NEXT_MONTH_DAY,     // 下个月的天数CURR_MONTH_DAY,     // 当月天数WEEKEND_DAY,        // 周末CURRENT_DAY,        // 当天
} E_DAY;///
/// \brief The DayLabel class
/// 自定义的日子显示控件
///
class DayLabel : public QLabel {Q_OBJECTpublic:explicit DayLabel(QWidget *parent = 0);bool bSelect;bool getBSelect() const;void setSelected(bool value);void setColor(const int &type);void showDay(int nDay, QString strLunar);int m_nDay;void setPlan(QStringList plan);
signals:void signalClicked(int ntype, int day);void signalPlan(const QString &content);
private:QLabel *labelIcon;QStringList m_strListPlan;
protected:void enterEvent(QEvent *e);void leaveEvent(QEvent *e);void mousePressEvent(QMouseEvent *e);void mouseDoubleClickEvent(QMouseEvent *e);
};/
/// \brief The CalendarWidget class
/// 日历界面class CalendarWidget : public QWidget
{Q_OBJECTpublic:explicit CalendarWidget(QWidget *parent = 0);~CalendarWidget();int year() const;void setYear(int year);int month() const;void setMonth(int month);int day() const;void setDay(int day);void jumpTodate(int year, int month, int day);
signals:void signalDayClicked(int nday);void signalDayChanged();void signalPlan(const QString &content);
private:QVBoxLayout *verLayoutCalendar;QWidget *widgetTitle;QLabel *labelTitle;QPushButton *btnPrevMonth;QPushButton *btnNextMonth;QHBoxLayout *horLayoutTitle;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;QVBoxLayout *verlayoutWidgetRight;QHBoxLayout *horLayoutGlobal;private:int m_nYear;int m_nMonth;int m_nDay;
private:void initWidget();<pre name="code" class="cpp">#include "calendarwidget.h"
.cpp

#include "date.h"
#include "database.h"#include <QInputDialog>
#include <QPainter>
#include <QStyleOption>
#include <QDateTime>
#include <QPushButton>
#include <QLineEdit>
#include <QGroupBox>
#include <QLabel>
#include <QDate>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QSpacerItem>
#include <QDebug>
#include <QFont>static const QString s_strWeek[] = {QObject::tr("周日"), QObject::tr("周一"), QObject::tr("周二"),QObject::tr("周三"), QObject::tr("周四"), QObject::tr("周五"),QObject::tr("周六"),
};CalendarWidget::CalendarWidget(QWidget *parent): QWidget(parent), m_nMonth(1)
{// 获取当前年月日m_nYear  = QDate::currentDate().year();m_nMonth = QDate::currentDate().month();m_nDay = QDate::currentDate().day();initWidget();initDate();
}CalendarWidget::~CalendarWidget()
{}int CalendarWidget::year() const
{return m_nYear;
}void CalendarWidget::setYear(int nYear)
{m_nYear = nYear;
}int CalendarWidget::month() const
{return m_nMonth;
}void CalendarWidget::setMonth(int nMonth)
{m_nMonth = nMonth;
}int CalendarWidget::day() const
{return m_nDay;
}void CalendarWidget::setDay(int nDay)
{m_nDay = nDay;
}void CalendarWidget::jumpTodate(int year, int month, int day)
{setYear(year);setMonth(month);setDay(day);initDate();
}/*** @brief CalendarWidget::initWidget 初始化界面*/
void CalendarWidget::initWidget()
{
#ifdef Q_OS_ANDROIDthis->setMinimumSize(1400, 800);
#elsethis->setMinimumSize(427, 350);this->setObjectName("widgetCalendar");
#endifverLayoutCalendar = new QVBoxLayout(this);verLayoutCalendar->setContentsMargins(2, 2, 2, 2);verLayoutCalendar->setSpacing(0);//! [2]widgetTitle = new QWidget(this);widgetTitle->setObjectName("widgetTitle");#ifdef Q_OS_ANDROIDwidgetTitle->setFixedHeight(80);
#elsewidgetTitle->setMinimumHeight(20);
#endifbtnPrevMonth = new QPushButton(widgetTitle);btnPrevMonth->setText(tr("上月"));labelTitle = new QLabel(widgetTitle);labelTitle->setAlignment(Qt::AlignCenter);labelTitle->setObjectName("labelTitle");labelTitle->setText(tr("2016 年 04 月"));btnNextMonth = new QPushButton(widgetTitle);btnNextMonth->setText(tr("下月"));horLayoutTitle = new QHBoxLayout(widgetTitle);horLayoutTitle->addWidget(btnPrevMonth);horLayoutTitle->addWidget(labelTitle, 1);horLayoutTitle->addWidget(btnNextMonth);verLayoutCalendar->addWidget(widgetTitle);connect(btnPrevMonth, SIGNAL(clicked(bool)), this, SLOT(sltShowPrevMonth()));connect(btnNextMonth, SIGNAL(clicked(bool)), this, SLOT(sltShowNextMonth()));//! [2]//! [3]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);}horLayoutWeek->addWidget(labelWeek[i]);}verLayoutCalendar->addWidget(widgetWeek);//! [3]//! [4]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)));connect(labelDay[i], SIGNAL(signalPlan(QString)), this, SIGNAL(signalPlan(QString)));}labelDay[10]->setSelected(true);//! [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);// 显示当前年月labelTitle->setText(tr("%1 年 %2 月").arg(m_nYear, 2, 10, QChar('0')).arg(m_nMonth, 2, 10, QChar('0')));// 显示上月剩余天数if (0 == nWeek) {// 显示上月天数for (int i = 0; i < 7; i++) {labelDay[i]->showDay((nPreMonDays - 7 + i + 1), "");labelDay[i]->setColor(PREV_MONTH_DAY);}// 显示下月天数for (int i = 0; i < (42 - nMonthDays - 7); i++) {labelDay[nMonthDays + 7 + i]->showDay((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), "");labelDay[i]->setColor(PREV_MONTH_DAY);}// 显示下月天数for (int i = (nWeek + nMonthDays); i < 42; i++) {labelDay[i]->showDay((i - (nWeek + nMonthDays) + 1), "");labelDay[i]->setColor(NEXT_MONTH_DAY);}}// 显示当前月int nProperty = 1;QStringList strPlan;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);// 显示计划strPlan = DataBase::selectDb(QString("%1-%2-%3").arg(m_nYear, 4, 10,  QChar('0')).arg(m_nMonth, 2, 10, QChar('0')).arg(i - nWeek + 1, 2, 10,   QChar('0')));// 显示计划labelDay[index]->setPlan(strPlan);}// 显示当前天数labelDay[m_nDay + nWeek - 1]->setColor(CURRENT_DAY);// 发送更新信号Q_EMIT signalDayChanged();
}/*** @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)) {// 选中当天Q_EMIT signalDayClicked(day);}
}/*** @brief CalendarWidget::sltShowPrevMonth 显示上月日期*/
void CalendarWidget::sltShowPrevMonth()
{m_nMonth--;if (m_nMonth < 1) {m_nMonth = 12;m_nYear--;}initDate();
}/*** @brief CalendarWidget::sltShowNextMonth 显示下月日期*/
void CalendarWidget::sltShowNextMonth()
{m_nMonth++;if (m_nMonth > 12) {m_nMonth = 1;m_nYear++;}initDate();
}//
/// \brief DayLabel::DayLabel
/// \param parent#include <QMouseEvent>
#include <QEvent>
#include <QPixmap>
#include "event.h"DayLabel::DayLabel(QWidget *parent):QLabel(parent)
{bSelect = false;m_nDay = 0;m_strListPlan.clear();labelIcon = new QLabel(this);labelIcon->setFixedSize(QSize(12, 12));labelIcon->setPixmap(QPixmap(":/images/eventindicator.png"));labelIcon->move(0, 0);labelIcon->setVisible(false);
}bool DayLabel::getBSelect() const
{return bSelect;
}void DayLabel::setSelected(bool value)
{bSelect = value;this->setStyleSheet(QString("background: #ffffff; border: 1px solid red; border-radius: 2px"));
}void DayLabel::setColor(const int &type)
{// 设置控件属性类型this->setProperty("type", type);this->setSelected(CURRENT_DAY == type);// 其他月if ((PREV_MONTH_DAY == type) || (NEXT_MONTH_DAY == type)) {this->setStyleSheet("background: #ffffff; border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; color: #999999;");labelIcon->setVisible(false);}// 当前月else if (CURR_MONTH_DAY == type) {this->setStyleSheet("background: #ffffff; border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; color: #000000;");}// 周末else if (WEEKEND_DAY == type) {labelIcon->setVisible(false);this->setStyleSheet("background: #ffffff; border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; color: #ff0000;");}
}/*** @brief DayLabel::showDay* @param nDay* @param strLunar* @param type*/
void DayLabel::showDay(int nDay, QString strLunar)
{QString strText = QString::number(nDay);this->m_nDay = nDay;if ("" != strLunar) {strText.append("\n");strText.append(strLunar);}this->setText(strText);
}/*** @brief DayLabel::setPlan 设置计划和日程* @param plan*/
void DayLabel::setPlan(QStringList plan)
{if (!plan.isEmpty()) {m_strListPlan = plan;this->setToolTip(m_strListPlan.at(1));}else {labelIcon->setVisible(false);m_strListPlan.clear();}
}void DayLabel::enterEvent(QEvent *e)
{int nProperty = this->property("type").toInt();if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return;this->setStyleSheet("background: #c8b9a6; border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3;");QLabel::enterEvent(e);
}void DayLabel::leaveEvent(QEvent *e)
{int nProperty = this->property("type").toInt();if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return;if (bSelect) {this->setStyleSheet("background: #ffffff; border: 1px solid red;");}else {this->setStyleSheet("background: #ffffff; border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3;");}QLabel::leaveEvent(e);
}void DayLabel::mousePressEvent(QMouseEvent *e)
{
//    qDebug() << this->text() << this->property("type").toInt();Q_EMIT signalClicked(this->property("type").toInt(), m_nDay);if (!m_strListPlan.isEmpty()) {Q_EMIT signalPlan(m_strListPlan.at(1));}else {Q_EMIT signalPlan(tr("没有日程安排"));}QLabel::mousePressEvent(e);
}void DayLabel::mouseDoubleClickEvent(QMouseEvent *e)
{//    qDebug() << "double";int nProperty = this->property("type").toInt();if (PREV_MONTH_DAY == nProperty || NEXT_MONTH_DAY == nProperty) return;bool ok;QString strText = "";if (!m_strListPlan.isEmpty()) {strText = m_strListPlan.at(1);}strText = QInputDialog::getText(this, tr("修改日程"),tr("您的出行计划"), QLineEdit::Normal,strText, &ok);if (ok && !strText.isEmpty())qDebug() << strText;QLabel::mouseDoubleClickEvent(e);
}//
/// \brief Window::Window
/// \param parent
/#include <QMessageBox>
#include "database.h"Window::Window(QWidget *parent) :QWidget(parent)
{// 初始化数据库DataBase::connectdb();initWidget();initStyle();initDatabase();
}Window::~Window()
{
}void Window::initWidget()
{//! [1]calendar = new CalendarWidget(this);//! [1]//! [2]widgetRight     = new QWidget(this);widgetRight->setObjectName("widgetRight");
//    widgetRight->setMinimumSize(160, 350);labelShowToday       = new QLabel(widgetRight);labelShowWeek        = new QLabel(widgetRight);labelShowDay         = new QLabel(widgetRight);labelShowNYear       = new QLabel(widgetRight);labelShowLunarDate   = new QLabel(widgetRight);labelSpacer          = new QLabel(widgetRight);labelPlanTitle   = new QLabel(widgetRight);labelShowPlan        = new QLabel(widgetRight);labelShowToday->setAlignment(Qt::AlignCenter);labelShowWeek->setAlignment(Qt::AlignCenter);labelShowDay->setAlignment(Qt::AlignCenter);labelShowNYear->setAlignment(Qt::AlignCenter);labelShowLunarDate->setAlignment(Qt::AlignCenter);labelSpacer->setFixedSize(widgetRight->width(), 2);labelShowToday->setObjectName("labelCommon");labelShowWeek->setObjectName("labelCommon");labelShowDay->setObjectName("labelShowDay");labelShowNYear->setObjectName("labelCommon");labelShowLunarDate->setObjectName("labelCommon");labelSpacer->setObjectName("labelSpacer");labelPlanTitle->setObjectName("labelCommon");labelShowPlan->setObjectName("labelSchedule");labelShowToday->setText(QDateTime::currentDateTime().toString("yyyy 年 MM 月 dd日"));labelShowWeek->setText(QDate::currentDate().toString("ddd"));labelShowDay->setText(QDate::currentDate().toString("dd"));labelShowNYear->setText(tr("丙申猴年 壬辰月 甲子日"));labelShowLunarDate->setText(tr("农历 三月初六"));labelPlanTitle->setText(tr("今日行程安排"));labelShowPlan->setText(tr("今天需要完成数据采集工作!"));labelShowPlan->setWordWrap(true);verlayoutWidgetRight = new QVBoxLayout(widgetRight);verlayoutWidgetRight->setContentsMargins(0, 0, 0, 0);verlayoutWidgetRight->setSpacing(15);verlayoutWidgetRight->addWidget(labelShowToday);verlayoutWidgetRight->addWidget(labelShowWeek);verlayoutWidgetRight->addWidget(labelShowDay);verlayoutWidgetRight->addWidget(labelShowNYear);verlayoutWidgetRight->addWidget(labelShowLunarDate);verlayoutWidgetRight->addWidget(labelSpacer, 0, Qt::AlignCenter);verlayoutWidgetRight->addStretch(1);verlayoutWidgetRight->addWidget(labelPlanTitle);verlayoutWidgetRight->addWidget(labelShowPlan, 1);//! [2]horLayoutWidget = new QHBoxLayout();horLayoutWidget->addWidget(calendar, 3, Qt::AlignCenter);horLayoutWidget->addWidget(widgetRight, 1);//! [3]groupBoxBottom = new QGroupBox(this);labelYearJump = new QLabel(groupBoxBottom);labelMonthJump = new QLabel(groupBoxBottom);labelDayJump = new QLabel(groupBoxBottom);labelYearJump->setMinimumWidth(20);labelMonthJump->setMinimumWidth(20);labelDayJump->setMinimumWidth(20);labelYearJump->setObjectName("labelCommon");labelMonthJump->setObjectName("labelCommon");labelDayJump->setObjectName("labelCommon");labelYearJump->setText(tr("年:"));labelMonthJump->setText(tr("月:"));labelDayJump->setText(tr("日:"));///editYearJump = new QLineEdit(groupBoxBottom);editMonthJump = new QLineEdit(groupBoxBottom);editDayJump = new QLineEdit(groupBoxBottom);editYearJump->setMaximumWidth(60);editMonthJump->setMaximumWidth(60);editDayJump->setMaximumWidth(60);editYearJump->setText("2016");editMonthJump->setText("1");editDayJump->setText("1");//btnDateJump = new QPushButton(groupBoxBottom);btnDateJump->setText(tr("跳转至该日期"));btnToday = new QPushButton(groupBoxBottom);btnToday->setText(tr("返回今天"));horLayoutJump = new QHBoxLayout(groupBoxBottom);horLayoutJump->setSpacing(10);horLayoutJump->addWidget(labelYearJump);horLayoutJump->addWidget(editYearJump);horLayoutJump->addWidget(labelMonthJump);horLayoutJump->addWidget(editMonthJump);horLayoutJump->addWidget(labelDayJump);horLayoutJump->addWidget(editDayJump);horLayoutJump->addStretch(1);horLayoutJump->addWidget(btnDateJump);horLayoutJump->addWidget(btnToday);//! [3]//! [4]verLayoutAll = new QVBoxLayout(this);verLayoutAll->setContentsMargins(10, 10, 10, 10);verLayoutAll->setSpacing(10);verLayoutAll->addLayout(horLayoutWidget, 1);verLayoutAll->addWidget(groupBoxBottom, 0);//! [4]connect(calendar, SIGNAL(signalDayChanged()), this, SLOT(sltDayChanged()));connect(calendar, SIGNAL(signalDayClicked(int)), this, SLOT(sltDayClicked(int)));connect(calendar, SIGNAL(signalPlan(QString)), this, SLOT(sltShowPlans(QString)));connect(btnDateJump, SIGNAL(clicked(bool)), this, SLOT(sltDateJump()));connect(btnToday, SIGNAL(clicked(bool)), this, SLOT(sltBack2today()));
}void Window::initDatabase()
{
}/*** @brief CalendarWidget::initStyle 初始化样式*/
void Window::initStyle()
{QString strStyle = "";
#ifdef Q_OS_ANDROIDstrStyle += QString(".CalendarWidget {border: 1px solid #ff00ff;}");strStyle += QString(".Window {background: black;}");strStyle += QString(".DayLabel{font-size: 64px;}");strStyle += QString("QWidget#widgetRight{background-color: transparent;}");strStyle += QString("QWidget#widgetCalendar{ background-color: white;}");strStyle += QString("QWidget#widgetTitle{ background-color: #c8b9a6;}");strStyle += QString("QWidget#widgetWeek{ background-color: #efefef;}");strStyle += QString("QLabel#labelTitle {border: none; font: bold 18px;}");strStyle += QString("QLabel#labelWeek {border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; font: bold 12px;}");strStyle += QString("QLabel#labelDay[weekend=true],QLabel#labelWeek[weekend=true]{color: red;}");strStyle += QString("QLabel#labelDay {border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; font-size: 14px;}");strStyle += QString("QLabel#labelShowDay {color: yellow; font: bold 64px;}");strStyle += QString("QLabel#labelCommon {background-color: transparent;color: #ffffff;}");strStyle += QString("QLabel#labelSchedule {background-color: transparent;color: #ffffff; border: 1px solid #ffffff;}");strStyle += QString("QLabel#labelSpacer {border: 1px solid #ffffff;}");strStyle += QString("QLineEdit {border: 1px solid #ffffff; border-radius: 5px; font-size: 20px;}");#elsestrStyle += QString(".CalendarWidget {border: 1px solid #ff00ff;}");strStyle += QString(".Window {background: black;}");strStyle += QString(".DayLabel{font: 24px; font-family: 隶书;}");strStyle += QString("QWidget#widgetCalendar{ background-color: white;}");strStyle += QString("QWidget#widgetTitle{ background-color: #c8b9a6;}");strStyle += QString("QWidget#widgetWeek{ background-color: #efefef;}");strStyle += QString("QLabel#labelTitle {border: none; font: bold 18px;}");strStyle += QString("QLabel#labelWeek {border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; font: bold 12px;}");strStyle += QString("QLabel#labelDay[weekend=true],QLabel#labelWeek[weekend=true]{color: red;}");strStyle += QString("QLabel#labelDay {border-top: 1px solid #c3c3c3; border-left: 1px solid #c3c3c3; font-size: 14px;}");strStyle += QString("QLabel#labelShowDay {color: yellow; font: bold 64px;}");strStyle += QString("QLabel#labelCommon {color: #ffffff;}");strStyle += QString("QLabel#labelSchedule {color: #ffffff; border: 1px solid #ffffff;}");strStyle += QString("QLabel#labelSpacer {border: 1px solid #ffffff;}");strStyle += QString("QLineEdit {border: 1px solid #ffffff; border-radius: 5px; font-size: 20px;}");
#endifthis->setStyleSheet(strStyle);
}void Window::sltDayClicked(int nday)
{labelShowDay->setText(QString("%1").arg(nday, 2, 10, QChar('0')));// 显示农历QString strLunar = Date::getLunarMonAndDay(calendar->year(), calendar->month(), nday);labelShowLunarDate->setText(tr("农历  %1").arg(strLunar));
}void Window::sltDayChanged()
{// 更新右边控件显示labelShowDay->setText(QString("%1").arg(calendar->day(), 2, 10, QChar('0')));// 显示农历QString strLunar = Date::getLunarMonAndDay(calendar->year(), calendar->month(), calendar->day());labelShowLunarDate->setText(tr("农历  %1").arg(strLunar));labelShowNYear->setText(Date::getLunarTime(calendar->year()));
}// 跳转日期
void Window::sltDateJump()
{int year = editYearJump->text().toInt();int month = editMonthJump->text().toInt();int day = editDayJump->text().toInt();int nMaxSet = 0;if ((year > 2040) || (year < 1970)) {QMessageBox::information(this, tr("提示"), tr("跳转年输入错误,请重新输入!"));editYearJump->setFocus();return;}if ((month > 12) || (month < 1)) {editMonthJump->setFocus();QMessageBox::information(this, tr("提示"), tr("跳转月输入错误,请重新输入!"));return;}if (2 == month) {nMaxSet = Date::isLoopYaer(year) ? 29 : 28;}else {nMaxSet = 31;}if ((day > nMaxSet) || (day < 1)) {editDayJump->setFocus();QMessageBox::information(this, tr("提示"), tr("跳转日输入错误,请重新输入!"));return;}// 跳转calendar->jumpTodate(year, month, day);
}/*** @brief Window::sltBack2today 跳转至今天*/
void Window::sltBack2today()
{int year = QDate::currentDate().year();int month = QDate::currentDate().month();int day = QDate::currentDate().day();// 跳转calendar->jumpTodate(year, month, day);
}/*** @brief Window::sltShowPlans 显示日程* @param content* @return*/
void Window::sltShowPlans(const QString &content)
{labelShowPlan->setText(content);
}void Window::paintEvent(QPaintEvent *)
{QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

然后就是农历的算法;

</pre></p><p></p><p><pre name="code" class="cpp">#ifndef DATE_H
#define DATE_H#include <QObject>class Date : public QObject
{Q_OBJECTpublic: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);
};#endif // DATE_H
#include "date.h"#include <QDebug>#define T_D_YAER   1924 //  天干地支开始计算年月//每年春节对应的公历日期
static const int springFestival[] = {130,217,206,                                // 1968,1969,1970127,215,203,123,211,131,218,207,128,216,    // 1971--1980205,125,213,202,220,209,219,217,206,127,    // 1981---1990215,204,123,210,131,219,207,128,216,205,    // 1991--2000124,212,201,122,209,129,218,207,126,214,    // 2001--2010203,123,210,131,219,208,128,216,205,125,    // 2011--2020                                       //2011--2020212,201,122,210,129,217,206,126,213,203,    // 2021--2030123,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,1970330077,1197,2637,268877,3365,531109,2900,2922,398042,2395,   // 1971--19801179,267415,2635,661067,1701,1748,398772,2742,2391,330031,   // 1981---19901175,1611,200010,3749,527717,1452,2742,332397,2350,3222,     // 1991--2000268949,3402,3493,133973,1386,464219,605,2349,334123,2709,    // 2001--20102890,267946,2773,592565,1210,2651,395863,1323,2707,265877,   // 2011--20201706,2773,133557,1206,398510,2638,3366,335142,3411,1450,     // 2021 -- 2030200042,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,     // 19700x96,0xB4,0x96,0xA6,0x97,0x97,0x78,0x79,0x79,0x69,0x78,0x77,     // 19710x96,0xA4,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 19720xA5,0xB5,0x96,0xA5,0xA6,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 19730x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87,     // 19740x96,0xB4,0x96,0xA6,0x97,0x97,0x78,0x79,0x78,0x69,0x78,0x77,     // 19750x96,0xA4,0xA5,0xB5,0xA6,0xA6,0x88,0x89,0x88,0x78,0x87,0x87,     // 19760xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 19770x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x78,0x87,     // 19780x96,0xB4,0x96,0xA6,0x96,0x97,0x78,0x79,0x78,0x69,0x78,0x77,     // 19790x96,0xA4,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 19800xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x77,0x87,     // 19810x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87,     // 19820x95,0xB4,0x96,0xA5,0x96,0x97,0x78,0x79,0x78,0x69,0x78,0x77,     // 19830x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87,     // 19840xA5,0xB4,0xA6,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 19850xA5,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87,     // 19860x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x79,0x78,0x69,0x78,0x87,     // 19870x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 19880xA5,0xB4,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87,     // 19890xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87,     // 19900x95,0xB4,0x96,0xA5,0x86,0x97,0x88,0x78,0x78,0x69,0x78,0x87,     // 19910x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 19920xA5,0xB3,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87,     // 19930xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 19940x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x76,0x78,0x69,0x78,0x87,     // 19950x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 19960xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 19970xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 19980x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87,     // 19990x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20000xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 20010xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 20020x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87,     // 20030x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20040xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 20050xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 20060x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x69,0x78,0x87,     // 20070x96,0xB4,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x87,0x78,0x87,0x86,     // 20080xA5,0xB3,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 20090xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 20100x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x78,0x87,     // 20110x96,0xB4,0xA5,0xB5,0xA5,0xA6,0x87,0x88,0x87,0x78,0x87,0x86,     // 20120xA5,0xB3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87,     // 20130xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 20140x95,0xB4,0x96,0xA5,0x96,0x97,0x88,0x78,0x78,0x79,0x77,0x87,     // 20150x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x87,0x88,0x87,0x78,0x87,0x86,     // 20160xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x87,     // 20170xA5,0xB4,0xA6,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 20180xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87,     // 20190x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x86,     // 20200xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20210xA5,0xB4,0xA5,0xA5,0xA6,0x96,0x88,0x88,0x88,0x78,0x87,0x87,     // 20220xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x79,0x77,0x87,     // 20230x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96,     // 20240xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20250xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 20260xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 20270x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96,     // 20280xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20290xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87,     // 20300xA5,0xB4,0x96,0xA5,0x96,0x96,0x88,0x78,0x78,0x78,0x87,0x87,     // 20310x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96,     // 20320xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x86,     // 20330xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x78,0x88,0x78,0x87,0x87,     // 20340xA5,0xB4,0x96,0xA5,0xA6,0x96,0x88,0x88,0x78,0x78,0x87,0x87,     // 20350x95,0xB4,0xA5,0xB4,0xA5,0xA6,0x97,0x87,0x87,0x78,0x87,0x96,     // 20360xA5,0xC3,0xA5,0xB5,0xA6,0xA6,0x87,0x88,0x88,0x78,0x87,0x86,     // 20370xA5,0xB3,0xA5,0xA5,0xA6,0xA6,0x88,0x88,0x88,0x78,0x87,0x87      // 2038
};static const char *s_pchDayName[] =  {("*"),("初一"), ("初二"), ("初三"), ("初四"), ("初五"),("初六"), ("初七"), ("初八"), ("初九"), ("初十"),("十一"), ("十二"), ("十三"), ("十四"), ("十五"),("十六"), ("十七"), ("十八"), ("十九"), ("二十"),("廿一"), ("廿二"), ("廿三"), ("廿四"), ("廿五"),("廿六"), ("廿七"), ("廿八"), ("廿九"), ("三十")
};/*农历月份名*/
static const char *s_pchMonName[] = {("*"),("正月"), ("二月"), ("三月"), ("四月"),("五月"), ("六月"), ("七月"), ("八月"),("九月"), ("十月"), ("冬月"), ("腊月")
};// 24节气
static const char *s_pchSolarTerm[] = {("小寒"), ("大寒"), ("立春"), ("雨水"), ("惊蛰"), ("春分"), ("清明"), ("谷雨"),("立夏"), ("小满"), ("芒种"), ("夏至"), ("小暑"), ("大暑"), ("立秋"), ("处暑"),("白露"), ("秋分"), ("寒露"), ("霜降"), ("立冬"), ("小雪"), ("大雪"), ("冬至")
};// 天干算法
static const char *s_pchTiangan[] = {("甲"), ("乙"), ("丙"), ("丁"), ("戊"),("己"), ("庚"), ("辛"), ("壬"), ("癸"),
};// 动物属性
static const char *s_pchAnimal[] = {("鼠"), ("牛"), ("虎"), ("兔"), ("龙"), ("蛇"),("马"), ("羊"), ("猴"), ("鸡"), ("狗"), ("猪"),
};// 地址算法
static const char *s_pchDizhi[] = {("子"), ("丑"), ("寅"), ("卯"), ("辰"), ("巳"),("午"), ("未"), ("申"), ("酉"), ("戌"), ("亥"),
};/*公历每月前面的天数*/
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() << springFestivalMonth << springFestivalDay;return (springFestivalMonth << 8) | springFestivalDay;
}int Date::getFirstDayOfWeek(int year, int month)
{int week = 0;// 获取当年1月1日是星期几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 计算农历* @param year  年* @param month 月* @param day 日* @return*/
QString Date::getLunarDate (int year, int month, int day){int nTheDate,nIsEnd,nMonTemp,k,n,nBit;// 先获取公历节日QString strDate = holiday(month, day);// 计算24节气QString strSolarTerms = solarTerms(year, month, day);/*现在计算农历:获得当年春节的公历日期(比如:2015年春节日期为(2月19日)),以此为分界点,2.19前面的农历是2014年农历(用2014年农历数据来计算),2.19以及之后的日期,农历为2015年农历(用2015年农历数据来计算)。*/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;}/*--计算农历天干、地支、月、日---*/nIsEnd = 0;while(nIsEnd != 1)  {if(nLunarData[nMonTemp] < 4095)k = 11;elsek = 12;n = k;while(n >= 0)   {// 获取wNongliData(m)的第n个二进制位的值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;}// 农历的年月日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;}// 显示装换的农历// only day == 1 ,return month nameif (1 == day) {if(month < 1){strDate = "闰" + tr(s_pchMonName[month * -1]);return strDate;}// 公历节日if ("" != strDate) return strDate;// 计算农历节日strDate = lunarFestival(month, day);// 如果有节日,直接显示if ("" == strDate) {// 如果当天不是24节气,显示农历日子strDate = strSolarTerms;if ("" == strDate) {strDate = tr(s_pchMonName[month]);}}} else {// 公历节日if ("" != strDate) return strDate;// 计算农历节日strDate = lunarFestival(month, day);// 如果有节日,直接显示if ("" == strDate) {// 如果当天不是24节气,显示农历日子strDate = strSolarTerms;if ("" == strDate) {strDate = tr(s_pchDayName[day]);}}}return strDate;
}/*** @brief Date::getLunarMonAndDay 响应点击时的农历显示* @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 = "";/*现在计算农历:获得当年春节的公历日期(比如:2015年春节日期为(2月19日)),以此为分界点,2.19前面的农历是2014年农历(用2014年农历数据来计算),2.19以及之后的日期,农历为2015年农历(用2015年农历数据来计算)。*/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;}/*--计算农历天干、地支、月、日---*/nIsEnd = 0;while(nIsEnd != 1)  {if(nLunarData[nMonTemp] < 4095)k = 11;elsek = 12;n = k;while(n >= 0)   {// 获取wNongliData(m)的第n个二进制位的值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;}// 农历的年月日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;}// 显示装换的农历// only day == 1 ,return month nameif (1 == day) {if (month < 1){strDate = tr("闰") + tr(s_pchMonName[month * -1]);return strDate;}strDate = tr(s_pchMonName[month]);} else {strDate = tr(s_pchMonName[month]) + tr(s_pchDayName[day]);}return strDate;
}/*** @brief Date::getLunarTime  计算今年是什么年如 :甲子年* @param year* @return*/
QString Date::getLunarTime(int year)
{int ntemp = 0;// 农历时辰QString strTime = "";if (year > T_D_YAER) {ntemp = year - T_D_YAER;strTime.append(tr(s_pchTiangan[ntemp % 10]));strTime.append(tr(s_pchDizhi[ntemp % 12]));strTime.append(tr(s_pchAnimal[ntemp % 12]));strTime.append(tr("年"));}return strTime;
}/*** @brief Date::holiday 公历假日* @param month* @param day* @return*/
QString Date::holiday(int month, int day)
{int temp = (month << 8) | day;QString strHoliday = "";switch (temp) {case 0x0101: strHoliday = tr("元旦");  break;case 0x020E: strHoliday = tr("情人节"); break;case 0x0308: strHoliday = tr("妇女节"); break;case 0x0401: strHoliday = tr("愚人节"); break;case 0x0501: strHoliday = tr("劳动节"); break;case 0x0504: strHoliday = tr("青年节"); break;case 0x0601: strHoliday = tr("儿童节"); break;case 0x0701: strHoliday = tr("建党节"); break;case 0x0801: strHoliday = tr("建军节"); break;case 0x090A: strHoliday = tr("教师节"); break;case 0x0A01: strHoliday = tr("国庆节"); break;case 0x0C18: strHoliday = tr("圣诞节"); break;default: break;}return strHoliday;
}/*** @brief Date::chineseTwentyFourDay 计算24节气* @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 tr(s_pchSolarTerm[2 * (month - 1)]);elsereturn "";} else if (day > 15) {dayTemp = day - 15;if((chineseTwentyFourData[index] & 0x0f) == dayTemp)return tr(s_pchSolarTerm[2 * (month - 1) + 1]);}return "";
}/*** @brief Date::lunarFestival 农历春节节日* @param month* @param day* @return 节日*/
QString Date::lunarFestival(int month, int day){int temp = (month << 8) | day;QString strFestival = "";switch (temp) {case 0x0101: strFestival = tr("春节");  break;case 0x010F: strFestival = tr("元宵节"); break;case 0x0202: strFestival = tr("龙抬头"); break;case 0x0505: strFestival = tr("端午节"); break;case 0x0707: strFestival = tr("七夕节"); break;case 0x080F: strFestival = tr("中秋节"); break;case 0x0909: strFestival = tr("重阳节"); break;case 0x0C08: strFestival = tr("腊八节"); break;default: break;}return strFestival;
}

代码里面我还添加了日程管理,不过未写完,留个位置在那里,以后心情好了在完善,至此核心代码已经完成。

给个源代码的下载地址吧:

http://download.csdn.net/detail/nigoole/9492904

Qt 制作带农历的日历相关推荐

  1. win7日历加入农历_还是农历更亲切,春节制作一个带农历的日历,欢欢喜喜过新年...

    2019带农历的日历 上图是用iSee图片专家制成的2019年2月份的台历,看上去就很豪华的样子,这个日历让我花费了不少的心血.其实,应该很多人都听说过iSee图片专家这个软件,它是一款功能十分全面的 ...

  2. vue —— 带农历的日历功能

    闲来无事做一些简单功能,一边练习VUE的使用,一边锻炼逻辑思维能力.之前有个项目需要自己写一个月份选择器,由此想起来做一个简单的日历,做起来有一些自己感兴趣的东西,也为了记录一下,发个帖 首先,我做的 ...

  3. 带节日和农历的js日历 带农历的脚本:

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  4. 带农历的中国万年历制作

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 最近一个 ...

  5. linux万年历,GDI+带农历的万年历(周历)之制作

    今天在网上无意中搜索到"Vista风格日历控件"().下载之后发现,略有BUG,于是进行改进.无意中,制作出来带农历的万年历(周历版). 运行如下图: 主要的改进在: // frm ...

  6. GDI+带农历的万年历(周历)之制作

    今天在网上无意中搜索到"Vista风格日历控件"(http://www.cnpopsoft.com/article.asp?id=56).下载之后发现,略有BUG,于是进行改进.无 ...

  7. WPF中制作带中国农历的万年历

    WPF中制作带中国农历的万年历 原文:WPF中制作带中国农历的万年历 本例应用.net 2.0中的ChineseLunisolarCalendar类,制作出带中国农历的万年历.  先看看效果图片(已缩 ...

  8. js 万年历农历转阳历 方法_JS实现带阴历的日历功能详解

    本文实例讲述了JS实现带阴历的日历功能.分享给大家供大家参考,具体如下: 工作中要写一个带阴历的日历,自己调研了怎么做日历. 一.表格行数问题 既然要显示日期表格的话,首先得知道这个表格有多少行多少列 ...

  9. 可以查询天气的日历——QT制作第一个自己的小软件

    目录 前言 一.ui界面 1.整体效果 2.主界面 3.天气查询 4.编辑日志 二.程序所有的文件 声明软件图标 1.widget.cpp 2.weather.cpp 3.text.cpp 4.mai ...

  10. 日历组件带农历及事件标记,绑定点击事件

    前段时间需要做一个课程日历的记事,还需要带农历,网上查了一下现有的日历带农历的代码分享,整合了一下自己的事件业务逻辑,最终做了这么一个日历组件(农历使用紫金山天文台农历编码1921-2023,有没有大 ...

最新文章

  1. python框架之Flask基础篇(一)
  2. ICCV2021最佳检测之一:主动学习框架较大提升目标检测精度(附论文下载)
  3. html 里运行php文件,如何在HTML文件中运行PHP脚本
  4. Lodash 中文文档 (v3.10.1) - “Lang” 方法
  5. 不是有效的win32应用程序_杀毒软件有坑!三分之二的安卓杀毒软件的“主业”并不是杀毒...
  6. 论文浅尝 - ACL2020 | 用于回答知识库中的多跳复杂问题的查询图生成方法
  7. smashing the stack for fun and profit 译文
  8. mac OS X下终端使用tree命令列目录
  9. 宽带波束形成 matlab,关于均匀圆阵MVDR宽带波束形成的程序
  10. 华硕主板如何设置开机自启_华硕主板怎么设置自动开机,华硕主板设置通电开机-...
  11. 在禁用UAC时,无法激活此应用
  12. 解决打印机后台程序服务没有运行
  13. 【单片机】2.9 看门狗定时器(WDT)功能简介
  14. 操作系统 存储管理实验报告
  15. 最薄的 4K 雷电 3 显示器 — ThinkVision X1 (2nd Gen) 长测
  16. Instant-Meshes-奇异点检测
  17. 斯坦福大学-自然语言处理入门 笔记 第十九课 单词含义与相似性
  18. Python 日志logging模块初探及多线程踩坑(2)
  19. 工业以太网交换机和普通交换机的区别 热设计为例
  20. 跟艾文学编程《零基础入门学Python》(4)Python 面向对象

热门文章

  1. 基于session推荐的论文阅读
  2. SprintBoot使用@Vaildated注解进行参数校验、全局异常处理以及注解校验不生效问题
  3. 安装VMware ESXi
  4. Python爬虫实战 - 抓取BOSS直聘职位描述 和 数据清洗
  5. 如何部署一个属于自己的网站
  6. android 实现果冻动画效果,手把手教你绘制Android粘性果冻动画组件
  7. win10创建新的计算机用户名和密码,win10电脑怎么新建用户?高手教你在win10新建用户的方法...
  8. 30天自制操作系统第8天harib05c
  9. 关于火车采集文章发布到wordpress后台待审核模块的设置
  10. Ubuntu 搭建opengrok 流程