利用Qt制作簡單的日期選擇界面
Qt自帶的日期選擇控件過于丑陋與難用,所以但凡有點小想法的人都會做一個全新的日歷。
這就是本人制作的日歷的截圖:

制作日歷的核心難點是填充日歷。以下為我的填充日歷函數(shù):
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();
當(dāng)日歷的日期被選擇時,會發(fā)送DateSelectSignal信號,調(diào)用者寫一個槽函數(shù)接受一下就可以:
void MyClass::HaveDateChose(QDate c_dates)
{
ui.dateedit->setDate(c_dates);
calandar_->accepted();
calandar_->deleteLater();
}
具體日歷的實現(xiàn)如下,當(dāng)然不想登錄的同志們可以通過百度網(wǎng)盤進(jìn)行下載:
百度網(wǎng)盤鏈接:
鏈接: 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 /* = 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());
}到此這篇關(guān)于利用Qt制作簡單的日期選擇界面的文章就介紹到這了,更多相關(guān)Qt日期選擇界面內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++產(chǎn)生隨機(jī)數(shù)的幾種方法小結(jié)
本文主要介紹了C++產(chǎn)生隨機(jī)數(shù)的幾種方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
基于WTL 雙緩沖(double buffer)繪圖的分析詳解
本篇文章是對WTL下使用雙緩沖(double buffer)繪圖進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++高精度計時的幾種方法總結(jié)(測試函數(shù)運行時間)
本文介紹了C++中常用的幾種程序計時方法,包括clock()函數(shù)、GetTickCount()、QueryPerformanceCounter()以及C++11中的chrono庫函數(shù),這篇文章主要介紹了C++高精度計時的幾種方法,需要的朋友可以參考下2024-09-09

