本文小编为大家详细介绍“怎么用Qt制作简单的日期选择界面”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Qt制作简单的日期选择界面”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
Qt自带的日期选择控件过于丑陋与难用,所以但凡有点小想法的人都会做一个全新的日历。
制作日历的核心难点是填充日历。以下为我的填充日历函数:
void STCalandarWidget::FillCalandar()
{
QDate firstDay;
firstDay.setDate(currentDate.year(), currentDate.month(), 1);
int firstnum = firstDay.dayOfWeek();//这个月的第一天是星期几
qDebug() << firstnum;
QDate firstDayOfMonth = firstDay.addDays(-(firstnum - 1));//日历的第一天实际的日期
for (int i = 0; i < 42; i++) {
if (i < firstnum-1 || (firstDayOfMonth.month() != currentDate.month())) {//理论上只需要后半边的条件就行
datewidgets[i]->SetDate(firstDayOfMonth.year(), firstDayOfMonth.month(), firstDayOfMonth.day(), false);
}
else {
datewidgets[i]->SetDate(firstDayOfMonth.year(), firstDayOfMonth.month(), firstDayOfMonth.day(), true);
}
firstDayOfMonth = firstDayOfMonth.addDays(1);
}
}
鄙人制作的日历使用起来非常简单,仅需将两个头文件和两个CPP加入到工程中,使用时的代码如下:
calandar_ = new STCalandarWidget(this);
connect(calandar_, SIGNAL(DateSelectSignal(QDate)), this, SLOT(HaveDateChose(QDate)));
calandar_->exec();
当日历的日期被选择时,会发送DateSelectSignal信号,调用者写一个槽函数接受一下就可以:
void MyClass::HaveDateChose(QDate c_dates)
{
ui.dateedit->setDate(c_dates);
calandar_->accepted();
calandar_->deleteLater();
}
STDateWidget.h:
#pragma once
#include <qwidget.h>
#include <QDate>
#include <QPainter>
class STDateWidget :
public QWidget
{
Q_OBJECT
public:
enum Direction {
DIR_TOP = 0,
DIR_BOTTOM,
DIR_LEFT,
DIR_RIGHT
};
STDateWidget(QWidget* parrent = nullptr);
~STDateWidget();
void SetDate(int year, int month, int day, bool isThisMonth);
QDate GetCurrentDate();
void AddNeighbor(STDateWidget* wid,Direction dir);
void HaveGoodNeighbor(Direction dir);
void DeleteGoodNgithbor(Direction dir);
private:
bool isHasGoodNeighbor;
bool canSelect;
bool isMoveIn;
Direction direction;
QDate currentDate;
QList<STDateWidget*> neighbors;
QList<Direction>directions;
protected:
void mouseReleaseEvent(QMouseEvent* event) ;
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
void paintEvent(QPaintEvent* event);
signals:
void updateCurrentDate(QDate date);
};
STDateWidget.cpp
#include "STDateWidget.h"
#include <QMouseEvent>
#include <QLinearGradient>
STDateWidget::STDateWidget(QWidget* parrent /* = nullptr */) :QWidget(parrent)
{
isMoveIn = false;
//qDebug() << "make";
//this->setGeometry(0, 0, 180, 160);
isHasGoodNeighbor = false;
//this->setStyleSheet("background-color:red");
}
STDateWidget::~STDateWidget()
{
}
void STDateWidget::SetDate(int year, int month, int day, bool isThisMonth)
{
currentDate.setDate(year, month, day);
canSelect = isThisMonth;
update();
}
QDate STDateWidget::GetCurrentDate()
{
return currentDate;
}
void STDateWidget::AddNeighbor(STDateWidget* wid, Direction dir)
{
neighbors.append(wid);
directions.append(dir);
}
void STDateWidget::HaveGoodNeighbor(Direction dir)
{
isHasGoodNeighbor = true;
direction = dir;
update();
}
void STDateWidget::DeleteGoodNgithbor(Direction dir)
{
isHasGoodNeighbor = false;
direction = dir;
update();
}
void STDateWidget::mouseReleaseEvent(QMouseEvent* event)
{
if (canSelect) {
emit updateCurrentDate(currentDate);
}
}
void STDateWidget::enterEvent(QEvent* event)
{
isMoveIn = true;
for (int i = 0; i < neighbors.count(); i++) {
neighbors[i]->HaveGoodNeighbor(directions[i]);
}
update();
}
void STDateWidget::leaveEvent(QEvent* event)
{
isMoveIn = false;
for (int i = 0; i < neighbors.count(); i++) {
neighbors[i]->DeleteGoodNgithbor(directions[i]);
}
update();
}
void STDateWidget::paintEvent(QPaintEvent* event)
{
//return;
QPainter painter(this);
painter.save();
int xx = 1;
int yy = 1;
int ww = this->geometry().width();
int hh = this->geometry().height();
if (isMoveIn) {
QPen pen;
pen.setBrush(QColor(0, 200, 250, 200));
pen.setWidth(2);
painter.setPen(pen);
painter.drawRect(xx +2 ,yy +2,ww-4,hh-4);
}
else {
if (isHasGoodNeighbor)
{
QPen pen;
pen.setBrush(QColor(255, 255, 255, 0));
pen.setWidth(0);
painter.setPen(pen);
QLinearGradient line_left_top2bottom(xx + 2, yy + 2, xx + 2, yy + hh - 6);//左。
line_left_top2bottom.setColorAt(0.0, Qt::white);
line_left_top2bottom.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_left_bottom2top( xx + 2, yy + hh - 6, xx + 2, yy + 2);//左。
line_left_bottom2top.setColorAt(0.0, Qt::white);
line_left_bottom2top.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_right_top2bottpm(xx + ww - 6, yy + 2, xx + ww - 6, yy + hh - 6);
line_right_top2bottpm.setColorAt(0.0, Qt::white);
line_right_top2bottpm.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_right_bottom2top(xx + ww - 6, yy + hh - 6, xx + ww - 6, yy + 2);
line_right_bottom2top.setColorAt(0.0, Qt::white);
line_right_bottom2top.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_top_left2right(xx + 2, yy + 2, xx + ww - 6, yy + 2);
line_top_left2right.setColorAt(0.0, Qt::white);
line_top_left2right.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_top_right2left(xx + ww - 6, yy + 2, xx + 2, yy + 2);
line_top_right2left.setColorAt(0.0, Qt::white);
line_top_right2left.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_bottom_left2right(xx + 2, yy + hh - 6, xx + ww - 6, yy + hh - 6);
line_bottom_left2right.setColorAt(0.0, Qt::white);
line_bottom_left2right.setColorAt(1.0, QColor(0, 200, 250, 100));
QLinearGradient line_bottom_right2left(xx + ww - 6, yy + hh - 6, xx + 2, yy + hh - 6);
line_bottom_right2left.setColorAt(0.0, Qt::white);
line_bottom_right2left.setColorAt(1.0, QColor(0, 200, 250, 100));
QRect rectTop(xx + 2, yy + 2, ww - 6, 2);
QRect rectBottom(xx + 2, yy + hh - 4, ww - 4, 2);
QRect rectLeft(xx + 2, yy + 2, 2, hh - 6);
QRect rectRight(xx + ww - 4, yy + 2, 2, hh - 6);
switch (direction)
{
case STDateWidget::DIR_TOP:
painter.setBrush(QColor(0, 200, 250, 100));
painter.drawRect(rectBottom);
painter.setBrush(line_left_top2bottom);
painter.drawRect(rectLeft);
painter.setBrush(line_right_top2bottpm);
painter.drawRect(rectRight);
break;
case STDateWidget::DIR_BOTTOM:
painter.setBrush(QColor(0, 200, 250, 100));
painter.drawRect(rectTop);
painter.setBrush(line_left_bottom2top);
painter.drawRect(rectLeft);
painter.setBrush(line_right_bottom2top);
painter.drawRect(rectRight);
break;
case STDateWidget::DIR_LEFT:
painter.setBrush(QColor(0, 200, 250, 100));
painter.drawRect(rectRight);
painter.setBrush(line_top_left2right);
painter.drawRect(rectTop);
painter.setBrush(line_bottom_left2right);
painter.drawRect(rectBottom);
break;
case STDateWidget::DIR_RIGHT:
painter.setBrush(QColor(0, 200, 250, 100));
painter.drawRect(rectLeft);
painter.setBrush(line_top_right2left);
painter.drawRect(rectTop);
painter.setBrush(line_bottom_right2left);
painter.drawRect(rectBottom);
break;
default:
break;
}
}
/* QPen pen;
pen.setBrush(QColor(255, 255, 255, 255));
pen.setWidth(2);
painter.setPen(pen);
painter.drawRect(this->geometry());*/
}
painter.restore();
if (canSelect) {
QPen pen2;
pen2.setBrush(QColor(0, 0, 0));
painter.setPen(pen2);
painter.drawText(ww/2 - 10, hh/2, QString::number(currentDate.day()));
}
else {
QPen pen2;
pen2.setBrush(QColor(200, 200, 200));
painter.setPen(pen2);
painter.drawText(ww/2- 10, hh/2, QString::number(currentDate.day()));
}
//painter
}
STCalandarWidget.h
#pragma once
#include <qdialog.h>
#include "STDateWidget.h"
#include <QLabel>
#include <QPushButton>
class STCalandarWidget :
public QDialog
{
Q_OBJECT
public:
STCalandarWidget(QWidget* parrent = nullptr);
~STCalandarWidget();
void SetCurrentDate(int year, int month, int day);
QDate GetCurrentDate();
private:
void FillCalandar();
void initLabels();
void initCalandar();
void init();
QString getFormatMonth();
private:
QLabel *weeklabels[7];
STDateWidget *datewidgets[42];
QPushButton *lastYearButton;
QPushButton *lastMonthButton;
QPushButton *nextMonthButton;
QPushButton *nextYearButton;
QDate currentDate;
QLabel *cdlabel;
public slots:
void HaveDateSelect(QDate date);
void JumpLastYear();
void JumpLastMonth();
void JumpNextMonth();
void JumpNextYear();
signals:
void DateSelectSignal(QDate date);
};
STCalandarWidget.cpp:
#include "STCalandarWidget.h"
#include <QDebug>
STCalandarWidget::STCalandarWidget(QWidget* parrent /* = nullptr */) :QDialog(parrent) {
this->setStyleSheet(QString::fromLocal8Bit("font:15px 等线; background-color:rgb(250,250,250)"));
this->setMinimumSize(580, 450);
this->setMaximumSize(580, 450);
Qt::WindowFlags flags = Qt::Dialog;
flags |= Qt::WindowCloseButtonHint;
setWindowFlags(flags);
init();
}
STCalandarWidget::~STCalandarWidget()
{
}
void STCalandarWidget::SetCurrentDate(int year, int month, int day)
{
currentDate.setDate(year, month, day);
}
QDate STCalandarWidget::GetCurrentDate()
{
return currentDate;
}
void STCalandarWidget::FillCalandar()
{
QDate firstDay;
firstDay.setDate(currentDate.year(), currentDate.month(), 1);
int firstnum = firstDay.dayOfWeek();
qDebug() << firstnum;
QDate firstDayOfMonth = firstDay.addDays(-(firstnum - 1));
for (int i = 0; i < 42; i++) {
if (i < firstnum-1 || (firstDayOfMonth.month() != currentDate.month())) {
datewidgets[i]->SetDate(firstDayOfMonth.year(), firstDayOfMonth.month(), firstDayOfMonth.day(), false);
}
else {
datewidgets[i]->SetDate(firstDayOfMonth.year(), firstDayOfMonth.month(), firstDayOfMonth.day(), true);
}
firstDayOfMonth = firstDayOfMonth.addDays(1);
}
}
void STCalandarWidget::initLabels()
{
for (int i = 0; i < 7; i++) {
weeklabels[i] = new QLabel(this);
weeklabels[i]->setGeometry(35 + i*80, 50, 80, 40);
}
weeklabels[0]->setText("Mon");
weeklabels[1]->setText("Tue");
weeklabels[2]->setText("Wed");
weeklabels[3]->setText("Thu");
weeklabels[4]->setText("Fri");
weeklabels[5]->setText("Sat");
weeklabels[6]->setText("Sun");
}
void STCalandarWidget::initCalandar()
{
for (int i = 0; i < 42; i++) {
datewidgets[i] = new STDateWidget(this);
datewidgets[i]->setGeometry(10 + i % 7 * 80, 80 + i / 7 * 60, 80, 60);
connect(datewidgets[i], SIGNAL(updateCurrentDate(QDate)), this, SLOT(HaveDateSelect(QDate)));
}
for (int i = 0; i < 42; i++) {
if (i / 7 == 0 ) {//第一排
if (i % 7 == 0) {//第一个
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
}
else if (i % 7 == 6) {//最后一个
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
else {
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
datewidgets[i]->AddNeighbor(datewidgets[i + 7], STDateWidget::DIR_BOTTOM);
}
else if (i / 7 == 5) {//最后一排
if (i % 7 == 0) {//第一个
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
}
else if (i % 7 == 6) {//最后一个
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
else {
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
datewidgets[i]->AddNeighbor(datewidgets[i - 7], STDateWidget::DIR_TOP);
}
else
{
if (i % 7 == 0) {//第一个
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
}
else if (i % 7 == 6) {//最后一个
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
else {
datewidgets[i]->AddNeighbor(datewidgets[i + 1], STDateWidget::DIR_RIGHT);
datewidgets[i]->AddNeighbor(datewidgets[i - 1], STDateWidget::DIR_LEFT);
}
datewidgets[i]->AddNeighbor(datewidgets[i - 7], STDateWidget::DIR_TOP);
datewidgets[i]->AddNeighbor(datewidgets[i + 7], STDateWidget::DIR_BOTTOM);
}
}
FillCalandar();
}
void STCalandarWidget::init()
{
currentDate = QDate::currentDate();
lastYearButton = new QPushButton(this);
lastYearButton->setGeometry(10, 10, 100, 30);
lastYearButton->setText("<<");
lastMonthButton = new QPushButton(this);
lastMonthButton->setGeometry(120, 10, 100, 30);
lastMonthButton->setText("<");
cdlabel = new QLabel(this);
cdlabel->setGeometry(255, 10, 100, 40);
cdlabel->setText(getFormatMonth());
nextMonthButton = new QPushButton(this);
nextMonthButton->setGeometry(360, 10, 100, 30);
nextMonthButton->setText(">");
nextYearButton = new QPushButton(this);
nextYearButton->setGeometry(470, 10, 100, 30);
nextYearButton->setText(">>");
connect(lastYearButton, SIGNAL(clicked()), this, SLOT(JumpLastYear()));
connect(lastMonthButton, SIGNAL(clicked()), this, SLOT(JumpLastMonth()));
connect(nextMonthButton, SIGNAL(clicked()), this, SLOT(JumpNextMonth()));
connect(nextYearButton, SIGNAL(clicked()), this, SLOT(JumpNextYear()));
initLabels();
initCalandar();
}
QString STCalandarWidget::getFormatMonth()
{
QString ans = "";
ans += QString::number(currentDate.year());
ans += QString::fromLocal8Bit("年");
ans += QString::number(currentDate.month());
ans += QString::fromLocal8Bit("月");
return ans;
}
void STCalandarWidget::HaveDateSelect(QDate date)
{
qDebug() << date;
emit DateSelectSignal(date);
}
void STCalandarWidget::JumpLastYear()
{
currentDate = currentDate.addYears(-1);
FillCalandar();
cdlabel->setText(getFormatMonth());
}
void STCalandarWidget::JumpLastMonth()
{
currentDate = currentDate.addMonths(-1);
FillCalandar();
cdlabel->setText(getFormatMonth());
}
void STCalandarWidget::JumpNextMonth()
{
currentDate = currentDate.addMonths(1);
FillCalandar();
cdlabel->setText(getFormatMonth());
}
void STCalandarWidget::JumpNextYear()
{
currentDate = currentDate.addYears(1);
FillCalandar();
cdlabel->setText(getFormatMonth());
}