行业知识
qt自定义时间选择控件窗口
2026-11-16 05:45:31
来源:互联网转载
���果如图:
布局如图:
参考代码:
//DateTimeSelectWidget#ifndef DATETIMESELECTWIDGET_H#define DATETIMESELECTWIDGET_H#include #include 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(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(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 #include #include #include #include #include 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 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() 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 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 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
上一篇:淄博联想服务器代理在哪里?