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();
}相关文章:
qt自定义时间选择控件窗口
效果如图: 布局如图: 参考代码: //DateTimeSelectWidget #ifndef DATETIMESELECTWIDGET_H #define DATETIMESELECTWIDGET_H#include <QWidget> #include <QDateTime>namespace Ui { class DateTimeSelectWidget; }class DateTim…...
如何不解压直接读取gzip文件里面的文件
要在服务器上不解压缩的情况下读取gzip文件中的文件内容,您可以使用类似于zlib模块的库,这些库允许您在内存中对gzip数据进行操作而无需解压缩到磁盘上的文件。 在Python中,您可以使用gzip模块来实现这一目的。以下是一个示例代码࿰…...
python 截取字符串string.split
目录 作用语法只要第一个值获得第3个值遍历 作用 根据某个符号对数据进行截取 从而获得自己想要的内容 语法 使用’string.split’ 方法 对字符串’123/abc/BPYC’ 以 ‘/’ 进行截取 string "123/abc/BPYC" substring string.split("/") print(subs…...
SpringBoot+Vue实现el-table表头筛选排序(附源码)
👨💻作者简介:在笑大学牲 🎟️个人主页:无所谓^_^ ps:点赞是免费的,却可以让写博客的作者开心好几天😎 前言 后台系统对table组件的需求是最常见的,不过element-ui的el…...
Linux学习之线程
目录 线程概念 1.什么是线程? 2.线程的优缺点 3.线程异常 4.线程用途 线程操作 1.如何给线程传参 2.线程终止 3.获取返回值 4.分离状态 5.退出线程 线程的用户级地址空间: 线程的局部存储 线程的同步与互斥 互斥量mutex 数据不一致的主要过…...
【JavaEE初阶】 JVM类加载简介
文章目录 🍃前言🌲类加载过程🚩加载🚩验证🚩准备🚩解析🚩初始化 🎄双亲委派模型🚩什么是双亲委派模型?🚩双亲委派模型的优点 ⭕总结 🍃…...
.NET Core依赖注入(IoC)不使用构造函数实现注入
在.NET Core中,依赖注入(IoC)通常是通过构造函数注入来实现的,这是推荐的方式,因为它使得依赖关系更加明确和可测试。但是,如果你不想或不能使用构造函数注入,你可以考虑使用方法注入࿰…...
WinSCP下载安装并结合内网穿透实现固定公网TCP地址访问本地服务器
文章目录 1. 简介2. 软件下载安装:3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件,它的主要功能是在本地与远程计…...
内联函数|auto关键字|范围for的语法|指针空值
文章目录 一、内联函数1.1概念1.2特性 二、auto关键字2.2类型别名思考2.3auto简介2.4auto使用细则2.4 auto不能推导的场景 三、基于范围的for循环(C11)3.1 范围for的语法 四、指针空值nullptr(C11)4.1 C98中的指针空值 所属专栏:C初阶 一、内联函数 1.1概念 以inline修饰的函…...
家用洗地机哪个型号好用?介绍几个值得考虑的品牌
作为家里的主要清洁工,我一直以来都是负责家里的清洁工作。我经常使用吸尘器和扫地机器人来轮流清洁,虽然效果还不错,但是这种方式太费时间和精力了。特别是在脸上厨房里做完饭和孩子吃完饭后留下的残渣时,我总是需要用传统的拖多…...
力扣-数组题
1. 两数之和 找出map中是否有target-nums[i], class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hash;for(int i 0 ;i < nums.size(); i){if(hash.find(target - nums[i]) ! hash…...
将List转换为数组或者将数组转换为List,如果改变了原始值,转换后的数据会发生改变吗?
将List转换为数组或将数组转换为List涉及到数据结构的变化。在Java中,这两种转换是否会影响原始数据取决于转换的方式和使用的数据结构。下面分别解释这两种情况: 将List转换为数组 当你将一个List转换为数组时,通常通过List的toArray()方法…...
七彩虹@电脑cpu频率上不去问题@控制中心性能模式cpu频率上不去@代理服务器超时@账户同步设置失败
文章目录 windows电脑cpu频率上不去新电脑的系统时间问题系统时间不准造成的具体问题举例代理超时vscode同步请求失败自动校准时间 windows电脑cpu频率上不去 问题描述,标压处理器的笔记本,cpu频率上不去 如果cpu没问题的话,就应该是系统限制了功耗导致的有的笔记本有控制中心…...
抖音怎么开店?抖音小店开店流程讲解,可收藏!
大家好,我是电商糖果 想在抖音上开一家小店,卖点东西,赚点儿辛苦钱。 如何正确的开通抖音小店呢? 这篇文章就给大家详细的讲解一下,帮大家规避掉一些百分之九十九的商家都会踩的坑。 近期开店的朋友,这…...
leetcode 热题 100_轮转数组
题解一: 新数组存储:另外用一个数组存储移动后的结果,再复制回原数组。 class Solution {public void rotate(int[] nums, int k) {int[] result new int[nums.length];for (int i 0; i < nums.length; i) {result[(i k) % nums.lengt…...
华为设备小型园区网方案(有线+无线+防火墙)
(一)配置有线部分 1.配置LSW2 (1)创建相关vlan [LSW2]vlan batch 10 3000 (2)配置连接LSW1的Eth-Trunk1,透传VLAN 10 3000 [LSW2]int Eth-Trunk 1 [LSW2-Eth-Trunk1]port link-type trunk [LSW2…...
硬件工程师入门基础知识(四)多层陶瓷电容应用(一)
多层陶瓷电容应用(一) 1.多层陶瓷电容器在电子电路中的主要作用以及对应的典型电路图有哪些?1.1 滤波电容1.2 退耦电容1.3 旁路电容1.4 耦合电容1.5 积分电容1.6 微分电容2.多层瓷介电容器能否超类别温度使用?3.瓷介电容器的工作电压如何选择?1.多层陶瓷电容器在电子电路中…...
python的虚拟环境
python的虚拟环境可以为项目创建一个独立的环境,能够解决使用不同版本依赖给项目带来冲突的麻烦。创建虚拟环境的方式有很多种,pipenv会自动帮你管理虚拟环境和依赖文件,并且提供了一系列命令和选项来帮忙你实现各种依赖和环境管理相关的操作…...
设计模式——2_4 中介者(Mediator)
我寄愁心与明月,随风直到夜郎西 ——李白《闻王昌龄左迁龙标遥有此寄》 文章目录 定义图纸一个例子:怎么调度一组地铁站台和地铁开车指挥中心 碎碎念中介者和表单平台思想但是这种平台便利性是要付出代价的变化隔离原则 姑妄言之 定义 用一个中介者对象…...
C语言教程(一)——输出、数据类型、表达式、条件判断、循环
一个C语言程序必须包含以下代码: int main(void){return 0; } 这是整个C语言程序的入口 输出 输入以下代码并运行(注意分号): #include <stdio.h>int main(void){printf("Hello World\n");return 0; }可以看…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
