当前位置: 首页 > news >正文

qt自定义时间选择控件窗口

效果如图:

在这里插入图片描述
布局如图:

在这里插入图片描述
参考代码:

//DateTimeSelectWidget
#ifndef DATETIMESELECTWIDGET_H
#define DATETIMESELECTWIDGET_H#include <QWidget>
#include <QDateTime>namespace Ui {
class DateTimeSelectWidget;
}class DateTimeSelectWidget : public QWidget
{Q_OBJECTpublic:explicit DateTimeSelectWidget(QWidget *parent = nullptr);~DateTimeSelectWidget();protected:void showEvent(QShowEvent *event);private:void init_wid_ui();void init_signal_and_slot();signals:void signal_snd_time_update(QString);private slots:void slot_btn_ok_clicked();void slot_update_cur_time_val(int val);private:Ui::DateTimeSelectWidget *ui;
};#endif
#include "datetimeselectwidget.h"
#include "ui_datetimeselectwidget.h"
#include "rollingtimewidget.h"DateTimeSelectWidget::DateTimeSelectWidget(QWidget *parent) :QWidget(parent),ui(new Ui::DateTimeSelectWidget)
{ui->setupUi(this);init_wid_ui();init_signal_and_slot();
}DateTimeSelectWidget::~DateTimeSelectWidget()
{delete ui;
}void DateTimeSelectWidget::showEvent(QShowEvent *event)
{QPushButton *btn = qobject_cast<QPushButton *>(parent());QString curDateTime = btn->text();QStringList list = curDateTime.split(" ");if(list.size() != 2)return;QString date = list[0];QString time = list[1];QStringList datelist = date.split("-");QStringList timelist = time.split(":");if(datelist.size()!=3 || timelist.size()!=3)return;ui->calendarWidget->setSelectedDate(QDate().fromString(date, "yyyy-MM-dd"));ui->wid_hour_select->setCurrTimeVal(QString(timelist[0]).toInt());ui->wid_minute_select->setCurrTimeVal(QString(timelist[1]).toInt());ui->wid_second_select->setCurrTimeVal(QString(timelist[2]).toInt());QWidget::showEvent(event);
}void DateTimeSelectWidget::init_wid_ui()
{this->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint);//设置时分秒的范围ui->wid_hour_select->setTimeRange(0,23);ui->wid_minute_select->setTimeRange(0,59);ui->wid_second_select->setTimeRange(0,59);
}void DateTimeSelectWidget::init_signal_and_slot()
{connect(ui->wid_hour_select, SIGNAL(signal_update_cur_time_val(int)), this, SLOT(slot_update_cur_time_val(int)));connect(ui->wid_minute_select, SIGNAL(signal_update_cur_time_val(int)), this, SLOT(slot_update_cur_time_val(int)));connect(ui->wid_second_select, SIGNAL(signal_update_cur_time_val(int)), this, SLOT(slot_update_cur_time_val(int)));connect(ui->btn_ok, SIGNAL(clicked()), this, SLOT(slot_btn_ok_clicked()));
}void DateTimeSelectWidget::slot_btn_ok_clicked()
{QDate curDate = ui->calendarWidget->selectedDate();if(curDate.isValid()){QString curDateTime = curDate.toString("yyyy-MM-dd");emit signal_snd_time_update(curDateTime);this->close();}
}void DateTimeSelectWidget::slot_update_cur_time_val(int val)
{QStringList list = ui->lab_hour_minute_second->text().split(":");if(list.size() != 3)return;RollingTimeWidget *wid = qobject_cast<RollingTimeWidget *>(sender());if(wid == ui->wid_hour_select){ui->lab_hour_minute_second->setText(QString("%1:%2:%3").arg(val).arg(list[1]).arg(list[2]));}else if(wid == ui->wid_minute_select){ui->lab_hour_minute_second->setText(QString("%1:%2:%3").arg(list[0]).arg(val).arg(list[2]));}else if(wid == ui->wid_second_select){ui->lab_hour_minute_second->setText(QString("%1:%2:%3").arg(list[0]).arg(list[1]).arg(val));}
}
//RollingTimeWidget
#ifndef ROLLINGTIMEWIDGET_H
#define ROLLINGTIMEWIDGET_H#include <QWidget>
#include <QMouseEvent>
#include <QPainter>
#include <QPropertyAnimation>
#include <QDateTime>
#include <QDebug>class RollingTimeWidget : public QWidget
{Q_OBJECT/* 将采用动画的对象属性注册到QT中去,否则动画将无法执行 */Q_PROPERTY(int posYShifting READ PosYShifting WRITE setPosYShifting)public:explicit RollingTimeWidget(QWidget *parent = nullptr);~RollingTimeWidget();/*** @brief setTimeRange 重新设置显示小时范围函数方法* @param int hour最小值* @param int hour最大值* @return void 无*/void setTimeRange(int min,int max); //设置重新设置范围/*** @brief PosYShifting 获取偏移量* @return int posYShifting*/int PosYShifting();/*** @brief setPosYShifting 设置偏移量* @param int 偏移量设置值* @return void 无*/void setPosYShifting(int posYShifting);void setCurrTimeVal(int val);protected:/*** @brief mousePressEvent 重写鼠标按压事件,鼠标拖动进行滚动* @param QMouseEvent* 鼠标按压事件* @return void 无*/void mousePressEvent(QMouseEvent *event)            override;/*** @brief wheelEvent 重写滚轮事件,滚轮进行滚动* @param QWheelEvent* 滚轮事件* @return void 无*/void wheelEvent(QWheelEvent *event)                 override;/*** @brief mouseMoveEvent 重写鼠标移动事件,鼠标移动进入滚动判决* @param QMouseEvent* 鼠标移动事件* @return void 无*/void mouseMoveEvent(QMouseEvent *event)             override;/*** @brief mouseReleaseEvent 重写鼠标松开事件,鼠标松开进入结果判决* @param QMouseEvent* 鼠标松开事件* @return void 无*/void mouseReleaseEvent(QMouseEvent *event)          override;/*** @brief paintEvent 重写绘图事件,对hour进行绘制* @param QPaintEvent* 绘图事件* @return void 无*/void paintEvent(QPaintEvent *paint)                 override;/*** @brief drawNumber 画出滚动数字函数* @param QPaintEvent* 画笔类导入* @param int 数字值value* @param int 滚动偏移量offset* @return void 无*/void drawNumber(QPainter &painter,int value,int offset);/*** @brief rollAnimation 滚动动画方法* @return void 无*/void rollAnimation();signals:void signal_update_cur_time_val(int val);private:/* 最小取值 */int min_Range = 0;/* 最大取值 */int max_Range = 0;/* 字体显示大小 */int numberSize = 5;/* 鼠标移动时判决器 */bool rollingJudgment = false;/* 记录按压鼠标时Y方向的初始位置 */int currentPosY = 0;/* 取系统的小时时间作为滚动时间选择的初始值 */int currentTime = 0;/* 当下的Y方向上的偏移量 */int posYShifting = 0;/* 声明一个动画对象 */QPropertyAnimation rollingAni;
};#endif // ROLLINGTIMEWIDGET_H
#include "rollingtimewidget.h"RollingTimeWidget::RollingTimeWidget(QWidget *parent):QWidget(parent)
{/* 去边框,同时保留窗口原有的属性 */this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());;/* 设置背景样式 */this->setStyleSheet("background:white;");/* 设置动画目标 */rollingAni.setTargetObject(this);/* 设置动画目标属性 */rollingAni.setPropertyName("posYShifting");/* 设置动画持续时间 */rollingAni.setDuration(500);/* 设置动画曲线样式 */rollingAni.setEasingCurve(QEasingCurve::OutCirc);
}RollingTimeWidget::~RollingTimeWidget()
{}void RollingTimeWidget::setTimeRange(int min, int max)
{min_Range = min;max_Range = max;update();
}int RollingTimeWidget::PosYShifting()
{/* 注册属性取值函数 */return posYShifting;
}void RollingTimeWidget::setPosYShifting(int posYShifting)
{/* 注册属性赋值函数 */this->posYShifting = posYShifting;update();
}void RollingTimeWidget::setCurrTimeVal(int val)
{currentTime = val;rollAnimation();update();
}void RollingTimeWidget::mousePressEvent(QMouseEvent *event)
{rollingAni.stop();/* 开启鼠标拖动滚动判决 */rollingJudgment = true;/* 刷新按下时鼠标位置 */currentPosY = event->pos().y();
}void RollingTimeWidget::wheelEvent(QWheelEvent *event)
{/* 以滚轮delta值正负性作为判决条件进行判决 */if(event->delta()>0){if(currentTime > min_Range){posYShifting = this->height()/4;}}else{if(currentTime < max_Range){posYShifting = - this->height()/4;}}rollAnimation();update();
}void RollingTimeWidget::mouseMoveEvent(QMouseEvent *event)
{if(rollingJudgment){if((currentTime == min_Range && event->pos().y() >= currentPosY) || (currentTime == max_Range && event->pos().y() <= currentPosY)){return;}else{posYShifting = event->pos().y() - currentPosY;}update();}
}void RollingTimeWidget::mouseReleaseEvent(QMouseEvent *event)
{Q_UNUSED(event);/*拖动判决归位*/if(rollingJudgment){rollingJudgment = false;/* 开启动画 */rollAnimation();}
}void RollingTimeWidget::paintEvent(QPaintEvent *paint)
{Q_UNUSED(paint);/* 创建画笔对象 */QPainter painter(this);/* 画笔抗锯齿操作 */painter.setRenderHint(QPainter::TextAntialiasing);painter.setRenderHint(QPainter::Antialiasing, true);/* 偏移量检测,以1/4高度和取值范围为边界 */if(posYShifting >= height() / 4 && currentTime > min_Range){/* 鼠标起始位置归位,即加上1/4的高度 */currentPosY += height()/4;/* 偏移量归位,即减去1/4的高度 */posYShifting -= height()/4;/* currentTime自减 */currentTime -= 1;}if(posYShifting <= -height() / 4 && currentTime < max_Range){currentPosY -= height() / 4;posYShifting += height() / 4;currentTime += 1;}/* 调用函数画出数字currentTime */drawNumber(painter,currentTime,posYShifting);/* 调用函数画出两侧数字 */if(currentTime != min_Range){drawNumber(painter,currentTime - 1,posYShifting - height() / 4);}if(currentTime != max_Range){drawNumber(painter,currentTime + 1,posYShifting + height() / 4);}/* 调用函数画出两侧数字 */if(posYShifting >= 0 && currentTime - 2 >= min_Range){drawNumber(painter,currentTime - 2,posYShifting - height() / 2);}if(posYShifting <= 0 && currentTime + 2 <= max_Range){drawNumber(painter,currentTime + 2,posYShifting + height() /  2);}/* 画出数字currentTime两侧边框 */painter.setPen(QPen(QColor(70,144,249),2));painter.drawLine(0,height() / 8 * 3,width(),height() / 8 * 3);painter.drawLine(0,height() / 8 * 5,width(),height() / 8 * 5);emit signal_update_cur_time_val(currentTime);
}void RollingTimeWidget::drawNumber(QPainter &painter, int value, int offset)
{/* 通过偏移量控制数字大小size */int size = (this->height() - abs(offset)) / numberSize;/* 通过偏移量控制数字透明度transparency */int transparency = 255 - 510 * abs(offset) / height();/* 通过偏移量控制数字在ui界面占据空间高度height */int height = this->height() / 2 - 3 * abs(offset) / 5;/* 计算数字显示位置 */int y = this->height() / 2 + offset - height / 2;QFont font;/* 设置字体大小 */font.setPixelSize(size);/* 画笔设置字体 */painter.setFont(font);/* 画笔设置颜色 */painter.setPen(QColor(0,0,0,transparency));/* 画笔painter画出文本*/painter.drawText(QRectF(0,y,width(),height),Qt::AlignCenter,(QString::number(value)));
}void RollingTimeWidget::rollAnimation()
{/* 动画判决,达到条件开启相应动画 */if(posYShifting > height() / 8){/* 设置属性动画初始value */rollingAni.setStartValue(height() / 8 - posYShifting);/* 设置属性动画终止value */rollingAni.setEndValue(0);/* currentTime值变更 */currentTime--;}else if(posYShifting > -height() / 8){/* 设置属性动画初始value */rollingAni.setStartValue(posYShifting);/* 设置属性动画终止value */rollingAni.setEndValue(0);}else if(posYShifting < -height() / 8){/* 设置属性动画初始value */rollingAni.setStartValue(-height() / 8 - posYShifting);/* 设置属性动画终止value */rollingAni.setEndValue(0);/* currentTime值变更 */currentTime++;}/* 动画开始 */rollingAni.start();update();
}
http://www.lryc.cn/news/313787.html

相关文章:

  • 如何不解压直接读取gzip文件里面的文件
  • python 截取字符串string.split
  • SpringBoot+Vue实现el-table表头筛选排序(附源码)
  • Linux学习之线程
  • 【JavaEE初阶】 JVM类加载简介
  • .NET Core依赖注入(IoC)不使用构造函数实现注入
  • WinSCP下载安装并结合内网穿透实现固定公网TCP地址访问本地服务器
  • 内联函数|auto关键字|范围for的语法|指针空值
  • 家用洗地机哪个型号好用?介绍几个值得考虑的品牌
  • 力扣-数组题
  • 将List转换为数组或者将数组转换为List,如果改变了原始值,转换后的数据会发生改变吗?
  • 七彩虹@电脑cpu频率上不去问题@控制中心性能模式cpu频率上不去@代理服务器超时@账户同步设置失败
  • 抖音怎么开店?抖音小店开店流程讲解,可收藏!
  • leetcode 热题 100_轮转数组
  • 华为设备小型园区网方案(有线+无线+防火墙)
  • 硬件工程师入门基础知识(四)多层陶瓷电容应用(一)
  • python的虚拟环境
  • 设计模式——2_4 中介者(Mediator)
  • C语言教程(一)——输出、数据类型、表达式、条件判断、循环
  • Prompt Engineering、Finetune、RAG:OpenAI LLM 应用最佳实践
  • [C语言]——分支和循环(4)
  • 【LeetCode】392. 判断子序列(简单)——代码随想录算法训练营Day54
  • 1. Typescript入门
  • 【Git】merge时报错:refusing to merge unrelated histories
  • 树状数组+离散化求逆序对超详细讲解!
  • 《解密云计算:企业之选》
  • 地址分词 | EXCEL批量进行地址分词,标准化为十一级地址
  • KubeSphere平台安装系列之二【Linux单节点部署KubeSphere】(2/3)
  • 网络安全: Kali Linux 使用 docker-compose 部署 openvas
  • 【学习考试心得】在誉天学习考试RHCE9.0的体验