本文小编为大家详细介绍“怎么用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_OBJECTpublic: 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 ) :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; } } } 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_OBJECTpublic: 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 ) :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());}
读到这里,这篇“怎么用Qt制作简单的日期选择界面”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。