13.QT-DateTime Edit|Dial|Slider|日期计算器|调整窗口透明度|调整窗口大小|自定义快捷键(C++)
Date Edit & Time Edit
使⽤ QDateEdit 作为⽇期的微调框.
 ![![[Pasted image 20250421101811.png]]](https://i-blog.csdnimg.cn/direct/ae614291fd734910841d536003232bd8.png)
使⽤ QTimeEdit 作为时间的微调框
 ![![[Pasted image 20250421101824.png]]](https://i-blog.csdnimg.cn/direct/3ef1db69d9d14ae9a257233aa9b4e28e.png)
使⽤ QDateTimeEdit 作为时间⽇期的微调框
 ![![[Pasted image 20250421101838.png]]](https://i-blog.csdnimg.cn/direct/f9670f38c8f7454db02e07bfddb02c06.png)
这⼏个控件⽤法⾮常相似,我们以 QDateTimeEdit 为例进⾏介绍.
QDateTimeEdit 核⼼属性
| 属性 | 说明 | 
|---|---|
| dateTime | 时间⽇期的值.形如 2000/1/1 0:00:00 | 
| date | 单纯⽇期的值.形如 2001/1/1 | 
| time | 单纯时间的值.形如 0:00:00 | 
| displayFormat | 时间⽇期格式.形如 yyyy/M/d H:mm • y 表⽰年份 • M 表⽰⽉份 • d 表⽰⽇期 • H 表⽰⼩时 • m 表⽰分钟 • s 表⽰秒 注意:这⾥的格式化符号的含义,不要记忆.不同语⾔/库的设定规则 是存在差异的.⼀定是⽤的时候再去查. | 
| minimumDateTime | 最⼩时间⽇期 | 
| maximumDateTime | 最⼤时间⽇期 | 
| timeSpec | • Qt::LocalTime :显⽰本地时间。 • Qt::UTC :显⽰协调世界时(UTC)。 • Qt::OffsetFromUTC :显⽰相对于UTC的偏移量(时差). | 
关于本地时间(LocalTime)和协调世界时(UTC)
 UTC时间是⼀个基于原⼦钟的标准时间.不受地球的⾃转周期影响.和格林威治时间(GMT)是⾮常接近的.科学家会通过精密的设备来测量并维护.
 咱们的计算机内部使⽤的时间就是基于UTC时间.
 本地时间则是基于不同的时区,对UTC时间做出了⼀些调整.⽐如咱们使⽤的北京时间,位于"东⼋区",就需要在UTC时间基础上+8个⼩时的时差
核⼼信号
| 信号 | 说明 | 
|---|---|
| dateChanged(QDate) | ⽇期改变时触发. | 
| timeChanged(QTime) | 时间改变时触发. | 
| dateTimeChanged(QDateTi me) | 时间⽇期任意⼀个改变时触发. | 
代码⽰例:实现⽇期计算器
1)在界⾯上创建两个 QDateTimeEdit 和⼀个按钮,⼀个label
 QDateTimeEdit 的 objectName 为 dateTimeEdit_old 和 dateTimeEdit_new
 ![![[Pasted image 20250421104256.png]]](https://i-blog.csdnimg.cn/direct/3f62877a8ede4b9e9a329848e26f11ce.png)
2)编写计算按钮的slot函数
- 使⽤ daysTo 函数可以计算两个⽇期的天数.
- 使⽤ secsTo 函数可以计算两个时间的秒数.
- 通过 (秒数 / 3600) 换算成⼩时数,再余上24得到零⼏个⼩时.
- 使⽤ QString::number 把整数转成 QString 进⾏拼接.
void Widget::on_pushButton_clicked()
{//获取到两个输入框的时间QDateTime timeOld = ui->dateTimeEdit->dateTime();QDateTime timeNew = ui->dateTimeEdit_2->dateTime();qDebug() << timeOld << timeNew;
}
![![[Pasted image 20250421104648.png]]](https://i-blog.csdnimg.cn/direct/c8d821fb59744c5c8d5fea5c50a904d1.png)
    //计算日期的差值int days = timeOld.daysTo(timeNew);qDebug() << days;
![![[Pasted image 20250421104946.png]]](https://i-blog.csdnimg.cn/direct/c44200fb9b8044dba2bde8e1db4635c1.png)
    //计算日期的差值int days = timeOld.daysTo(timeNew);int seconds = timeOld.secsTo(timeNew);//把秒数换算成小时int hours = (seconds / 3600) % 24;qDebug() << days << hours;
![![[Pasted image 20250421110203.png]]](https://i-blog.csdnimg.cn/direct/0ac2315e70444dbc8b79b822b352abaf.png)
void Widget::on_pushButton_clicked()
{//获取到两个输入框的时间QDateTime timeOld = ui->dateTimeEdit->dateTime();QDateTime timeNew = ui->dateTimeEdit_2->dateTime();qDebug() << timeOld << timeNew;//计算日期的差值int days = timeOld.daysTo(timeNew);int seconds = timeOld.secsTo(timeNew);//把秒数换算成小时int hours = (seconds / 3600) % 24;//把结果放到label中ui->label->setText(QString("时间持续了 ") + QString::number(days) + QString(" 天零 ") + QString::number(hours) + QString(" 小时"));
}
![![[Pasted image 20250421110648.png]]](https://i-blog.csdnimg.cn/direct/03e0a24ab99a49169fb17ad2e83b3675.png)
有bug,应该是7小时
 ![![[Pasted image 20250421110923.png]]](https://i-blog.csdnimg.cn/direct/a4f8fbd9963348a2af34c142c2022a6f.png)
void Widget::on_pushButton_clicked()
{//获取到两个输入框的时间QDateTime timeOld = ui->dateTimeEdit->dateTime();QDateTime timeNew = ui->dateTimeEdit_2->dateTime();qDebug() << timeOld << timeNew;//计算日期的差值//int days = timeOld.daysTo(timeNew);int seconds = timeOld.secsTo(timeNew);//把秒数换算成小时int hours = (seconds / 3600) % 24;int days = (seconds / 3600) / 24;//把结果放到label中ui->label->setText(QString("时间持续了 ") + QString::number(days) + QString(" 天零 ") +QString::number(hours) + QString(" 小时"));
}
如果当前得到的小时数不足24,
 由于此处是“整数除法",就会舍弃掉小数点后的内容得到的结果就是0了.
 ![![[Pasted image 20250421111712.png]]](https://i-blog.csdnimg.cn/direct/a431547bd7544363b5c2643de21fb015.png)
Dial
使⽤ QDial 表⽰⼀个旋钮.
 有些程序,通过⿏标拖动旋钮旋转,即可完成⼀些相关的设置.
 ![![[Pasted image 20250421111807.png]]](https://i-blog.csdnimg.cn/direct/983835c8c2ff4deeb6a82140a60606c8.png)
核⼼属性
| 属性 | 说明 | 
|---|---|
| value | 持有的数值. | 
| minimum | 最⼩值 | 
| maximum | 最⼤值 | 
| singleStep | 按下⽅向键的时候改变的步⻓. | 
| pageStep | 按下pageUp/pageDown的时候改变的步⻓. | 
| sliderPosition | 界⾯上旋钮显⽰的初始位置 | 
| tracking | 外观是否会跟踪数值变化. 默认值为true.⼀般不需要修改. | 
| wrapping | 是否允许循环调整. 即数值如果超过最⼤值,是否允许回到最⼩值. (调整过程能否"套圈") | 
| notchesVisible | 是否显⽰刻度线 | 
| notchTarget | 刻度线之间的相对位置. 数字越⼤,刻度线越稀疏. | 
核⼼信号
| 属性 | 说明 | 
|---|---|
| valueChanged(int) | 数值改变时触发 | 
| rangeChanged(int, int) | 范围变化时触发 | 
代码⽰例:调整窗⼝透明度
1)在界⾯上创建⼀个旋钮和⼀个label
 ![![[Pasted image 20250421123944.png]]](https://i-blog.csdnimg.cn/direct/93dd7fb79cf342e1ab1fce9e22ec9ecc.png)
初始值设置
 ![![[Pasted image 20250421124225.png]]](https://i-blog.csdnimg.cn/direct/6b1c88c4f65d45c1916c2afe6794cf19.png)
或者用代码初始化
Widget::Widget(QWidget *parent)  : QWidget(parent)  , ui(new Ui::Widget)  
{  ui->setupUi(this);  // 设置可以循环旋转  ui->dial->setWrapping(true);  // 设置刻度线可⻅  ui->dial->setNotchesVisible(true);  // 设置最⼤值为  ui->dial->setMaximum(100);  // 设置最⼩值为  ui->dial->setMinimum(0);  // 设置初始值为  ui->dial->setValue(100);  
}
3)编写widget.cpp,设置旋钮的 valueChanged slot函数
void Widget::on_dial_valueChanged(int value)
{qDebug() << value;ui->label->setText(QString("当前不透明度为: ") + QString::number(value));this->setWindowOpacity((double)value / 100);
}
![![[Pasted image 20250421130945.png]]](https://i-blog.csdnimg.cn/direct/01d551153e51422e9b35e03e01cf8684.png)
Slider
使⽤ QSlider 表⽰⼀个滑动条
 ![![[Pasted image 20250421131039.png]]](https://i-blog.csdnimg.cn/direct/ee37c7ce1aed4894b5b5f00d0255e0dd.png)
QSlider 和 QDial 都是继承⾃ QAbstractSlider ,因此⽤法上基本相同.
核⼼属性
| 属性 | 说明 | 
|---|---|
| value | 持有的数值. | 
| minimum | 最⼩值 | 
| maximum | 最⼤值 | 
| singleStep | 按下⽅向键的时候改变的步⻓. | 
| pageStep | 按下pageUp/pageDown的时候改变的步⻓. | 
| sliderPosition | 滑动条显⽰的初始位置 | 
| tracking | 外观是否会跟踪数值变化. 默认值为true.⼀般不需要修改. | 
| orientation | 滑动条的⽅向是⽔平还是垂直 | 
| invertedAppearance | 是否要翻转滑动条的⽅向 | 
| tickPosition | 刻度的位置. | 
| tickInterval | 刻度的密集程度. | 
核⼼信号
| 属性 | 说明 | 
|---|---|
| valueChanged(int) | 数值改变时触发 | 
| rangeChanged(int, int) | 范围变化时触发 | 
代码⽰例:调整窗⼝⼤⼩
1)在界⾯上创建两个滑动条,分别是⽔平和垂直滑动条.
 objectName 分别为 horizontalSlider 和 verticalSlider
 ![![[Pasted image 20250421132305.png]]](https://i-blog.csdnimg.cn/direct/fcab0806122e431480f729925463ffbf.png)
2)编写代码初始化滑动条
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->horizontalSlider->setMinimum(100);ui->horizontalSlider->setMaximum(2000);ui->horizontalSlider->setValue(800);ui->horizontalSlider->setSingleStep(50);ui->verticalSlider->setMinimum(100);ui->verticalSlider->setMaximum(1500);ui->verticalSlider->setValue(600);ui->verticalSlider->setSingleStep(50);// 翻转朝向, 默认滑块从下向上增⻓, 改成从上往下增⻓.ui->verticalSlider->setInvertedAppearance(true);
}
3)编写滑动条的 valueChanged slot函数
void Widget::on_horizontalSlider_valueChanged(int value)
{const QRect& rect = this->geometry();this->setGeometry(rect.x(), rect.y(), value, rect.height());
}void Widget::on_verticalSlider_valueChanged(int value)
{const QRect& rect = this->geometry();this->setGeometry(rect.x(), rect.y(), rect.width(), value);
}
4)执⾏程序,可以看到调整滑动条,窗⼝⼤⼩就会随之改变.
 ![![[Pasted image 20250421134322.png]]](https://i-blog.csdnimg.cn/direct/e4973e21e6034dac811ae02dd7d9a5be.png)
代码⽰例:通过⾃定义快捷键调整滑动条位置
设置-减⼩value,设置=增加value.
 默认情况下滑动条可以通过⽅向键或者pageUp/pageDown调整⼤⼩.
 1)在界⾯上创建滑动条和label
 ![![[Pasted image 20250421134754.png]]](https://i-blog.csdnimg.cn/direct/66f106f980454233974edabe1add27b1.png)
2)编写初始化代码
#include "widget.h"
#include "ui_widget.h"
#include <QShortcut>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->label->setText("");  ui->horizontalSlider->setMinimum(0);  ui->horizontalSlider->setMaximum(100);  ui->horizontalSlider->setSingleStep(10);  ui->horizontalSlider->setValue(0);
}
3)创建 valueChanged 的slot函数
void Widget::on_horizontalSlider_valueChanged(int value)
{ui->label->setText("当前的值为: " + QString::number(value));
}
4)修改widget.cpp构造函数,增加快捷键
- 使⽤ QShortCut 类设置快捷键.
- 快捷键触发时,会发出 QShortcut::activated 信号,我们连接到⾃⼰写的slot函数.
    //使用快捷键,需要QShortcut类//需要两个快捷键,-用于减少,=用于增加QShortcut* shortCut1 = new QShortcut(this);shortCut1->setKey(QKeySequence("-"));QShortcut* shortCut2 = new QShortcut(this);shortCut2->setKey(QKeySequence("="));//使用信号槽感知到快捷键被按下connect(shortCut1, &QShortcut::activated, this, &Widget::subValue);connect(shortCut2, &QShortcut::activated, this, &Widget::addValue);
5)编写⾃定义slot函数
void Widget::subValue()
{//获取当前的值int value = ui->horizontalSlider->value();if (value <= ui->horizontalSlider->minimum()) {return;}ui->horizontalSlider->setValue(value - 5);
}void Widget::addValue()
{//获取当前的值int value = ui->horizontalSlider->value();if (value >= ui->horizontalSlider->maximum()) {return;}ui->horizontalSlider->setValue(value + 5);
}
![![[Pasted image 20250421140359.png]]](https://i-blog.csdnimg.cn/direct/d0b7daa7c3404e7fb9dc3eda1e7330c6.png)
