Qt Demo:日历

开始学习Qt时做的一个小日历,可以实现上一年、上一月、下一月、下一年的跳转,以及输入指定日期跳转(回车或点击按钮)。

在需要展示的地方使用Calendar或将QWidget提升为Calendar即可。

Calendar.h

#ifndef CALENDAR_H
#define CALENDAR_H

#include <QWidget>
#include <QDate>
#include <QDebug>
#include <QSignalMapper>
namespace Ui {
class Calendar;
}

class Calendar : public QWidget
{
	Q_OBJECT

public:
	Calendar(QWidget *parent = nullptr);
	~Calendar();

	void shownowcalender(QDate _date);
	void clicked(QDate _date);
	void connectSignal();

private:
	Ui::Calendar *ui;
	QDate _date;
	QString graystyle = "QPushButton{"
						"background-color:rgb(230, 230, 230);"
						"color:gray;"
						"font:bold;"
						"border-radius:4px;"
						"}"
						"QPushButton:hover"
						"{"
						"background-color:rgba(69,80,93,0.4);"
						"}"
						"QPushButton:focus{border:5px solid #CFCFCF;}";
	QString whitestyle = "QPushButton{"
						 "background-color:rgb(120, 135, 135);"
						 "color:white;"
						 "font:bold;"
						 "border-radius:4px;"
						 "}"
						 "QPushButton:hover"
						 "{"
						 "background-color:rgba(69,80,93,0.4);"
						 "}"
						 "QPushButton:focus{border:5px solid #CFCFCF;}";
	QString _chooseDate;

signals:
	void send(QString);

private slots:
	void turnmonth(QString month);

	void on_btn_lastyear_clicked();
	void on_btn_lastmonth_clicked();
	void on_btn_nextmonth_clicked();
	void on_btn_nextyear_clicked();
	void on_btn_choosemonth_clicked();

	void on_btn_confirmed_clicked();
	void on_btn_close_clicked();

	void onChooseDate();
};

#endif // CALENDAR_H

Calendar.cpp

#include "Calendar.h"
#include "ui_Calendar.h"

/*
 * 构造函数
 */
Calendar::Calendar(QWidget *parent)
	: QWidget(parent, Qt::Popup)
	, ui(new Ui::Calendar)
	, _date(QDate::currentDate())
	, _chooseDate()
{
	ui->setupUi(this);
	clicked(_date);
	ui->stackedWidget->setCurrentIndex(0);
	connectSignal();
}

/*
 * 析构函数
 */
Calendar::~Calendar()
{
	delete ui;
}

/*
 * 生成对应日期日历
 */
void Calendar::shownowcalender(QDate date){

	//获取当前月份天数
	int monthdays = date.daysInMonth();
	//获取这个月第一天是周几
	QDate newday(date.year(),date.month(),1);
	//往前需要的天数
	int needday = newday.dayOfWeek()-1;
	//往后需要的天数
	int nextneedday = 42-monthdays-needday;
	//设置月底
	QDate last(date.year(),date.month(),monthdays);
	//获取当前月份
	int nowmonth = date.month();

	QDate nowday;
	//显示往前需要的日期
	for(int j=1;j<=needday;j++){
		nowday = newday.addDays(-j);
		QString days = nowday.toString("dd");
		QWidget * box = this->findChild<QWidget *>("widget_w"+QString::number(nowday.dayOfWeek()));
		QPushButton * PushButtonx = new QPushButton();
		PushButtonx->setFixedSize(45,25);
		PushButtonx->setStyleSheet(graystyle);

		//设置点击事件,发送日期信息
		connect(PushButtonx, SIGNAL(clicked()), this, SLOT(onChooseDate()));

		//显示按钮和文字
		box->layout()->addWidget(PushButtonx);
		PushButtonx->setText(days);
		QString name = nowday.toString("yyyy-MM-dd");
		PushButtonx->setObjectName(name);
		PushButtonx->show();
	}

	//输出当前月份日期
	for(int i=0;i<monthdays;i++){
		nowday = newday.addDays(i);
		//判断是否是当月
		int month = nowday.month();
		if(month == nowmonth){
			QString days = nowday.toString("dd");
			QWidget * box = this->findChild<QWidget *>("widget_w"+QString::number(nowday.dayOfWeek()));
			QPushButton * PushButtonx = new QPushButton();
			PushButtonx->setFixedSize(45,25);
			//添加颜色
			PushButtonx->setStyleSheet(whitestyle);

			//设置点击事件
			connect(PushButtonx, SIGNAL(clicked()), this, SLOT(onChooseDate()));

			//显示按钮和文字
			box->layout()->addWidget(PushButtonx);
			PushButtonx->setText(days);
			QString name = nowday.toString("yyyy-MM-dd");
			PushButtonx->setObjectName(name);
			PushButtonx->show();

		}

	}
	//显示往后需要的日期
	for(int j=1;j<=nextneedday;j++){
		nowday = last.addDays(j);
		QString days = nowday.toString("dd");
		QWidget * box = this->findChild<QWidget *>("widget_w"+QString::number(nowday.dayOfWeek()));
		QPushButton * PushButtonx = new QPushButton();
		PushButtonx->setFixedSize(45,25);
		//添加颜色
		PushButtonx->setStyleSheet(graystyle);

		connect(PushButtonx, SIGNAL(clicked()), this, SLOT(onChooseDate()));

		//显示按钮和文字turnmonth
		box->layout()->addWidget(PushButtonx);
		PushButtonx->setText(days);
		QString name = nowday.toString("yyyy-MM-dd");
		PushButtonx->setObjectName(name);
		PushButtonx->show();
	}

}

/*
 * 展示对应日期日历
 */
void Calendar::clicked(QDate date){
	//删除上次生成的按钮列表
	QList<QPushButton*> list=ui->widget_6->findChildren<QPushButton*>();
	for (int i = 0;i<list.length();i++) {
		delete list[i];
	}
	//执行展示整个当前日历 参数date可以随需求更改
	shownowcalender(date);
	//给显示年月按钮设置文字
	int a = date.year();
	int b = date.month();
	ui->btn_choosemonth->setText(QString::number(a)+"年"+QString::number(b)+"月");
}

/*
 * 跳转至上一年份
 */
void Calendar::on_btn_lastyear_clicked()
{
	_date = _date.addYears(-1);
	clicked(_date);
}

/*
 * 跳转至上一月份
 */
void Calendar::on_btn_lastmonth_clicked()
{
	_date = _date.addMonths(-1);
	clicked(_date);
}

/*
 * 跳转至下一月份
 */
void Calendar::on_btn_nextmonth_clicked()
{
	_date = _date.addMonths(1);
	clicked(_date);
}

/*
 * 跳转至下一年份
 */
void Calendar::on_btn_nextyear_clicked()
{
	_date = _date.addYears(1);
	clicked(_date);
}

/*
 * 跳转至选择月份界面
 */
void Calendar::on_btn_choosemonth_clicked()
{
	ui->stackedWidget->setCurrentIndex(1);
}

/*
 * 连接信号
 */
void Calendar::connectSignal(){
	QSignalMapper *pMapper = new QSignalMapper(this);
	QList<QToolButton *> nToolButton = ui->stackedWidget->widget(1)->findChildren<QToolButton *>();
	foreach(QToolButton * btn,nToolButton){
		connect(btn,SIGNAL(clicked()),pMapper,SLOT(map()));
		QString text = btn->text().left(btn->text().size()-1);
		pMapper->setMapping(btn,text);
	}
	connect(pMapper,SIGNAL(mapped(QString)),this,SLOT(turnmonth(QString)));
}

/*
 * 跳转至选中月份
 */
void Calendar::turnmonth(QString month){
	QDate now(_date.year(),month.toInt(),_date.day());
	_date = now;
	ui->stackedWidget->setCurrentIndex(0);
	clicked(_date);
}

/*
 * 获取选中日期
 */
void Calendar::onChooseDate()
{
	QPushButton* pButton = qobject_cast<QPushButton*>(sender());
	if(pButton)
	{
		_chooseDate = pButton->objectName();
	}
}

/*
 * 确认选中日期
 */
void Calendar::on_btn_confirmed_clicked()
{
	emit send(_chooseDate);
	this->close();
}

/*
 * 关闭日历窗口
 */
void Calendar::on_btn_close_clicked()
{
	this->close();
}

效果展示:
在这里插入图片描述
ui资源:
点此下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值