利用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();
}
具体日历的实现如下,当然不想登录的同志们可以通过百度网盘进行下载:
百度网盘链接:
链接: https://pan.baidu.com/s/1x8EMfKYP3t04ssG-UpoGMQ 提取码: vwqw
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 ) :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_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 ) :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制作简单的日期选择界面的文章就介绍到这了,更多相关Qt日期选择界面内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
相关文章