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

PyQt5 — QTimeEdit 学习笔记

第二章 控件学习


1. 概述

1.1 什么是 QTimeEdit?

        QTimeEdit 是 PyQt5 中专门用于时间选择的控件,继承自 QDateTimeEdit。它提供了一个简洁的界面,让用户可以通过上下箭头、键盘输入或自定义格式来选择时间。

1.2 与其他控件的关系

  • QTimeEdit 专注于时间选择
  • QDateEdit 专注于日期选择
  • QDateTimeEdit 可同时处理日期和时间
  • 三者均继承自 QAbstractSpinBox,共享基本的编辑和验证功能

1.3 主要用途

  • 会议时间、闹钟设置等时间输入
  • 工作时间、营业时间选择
  • 任何需要用户精确选择时间的场景

2. 基础使用

2.1 导入必要的模块

from PyQt5.QtWidgets import QApplication, QTimeEdit, QWidget, QVBoxLayout, QLabel
from PyQt5.QtCore import QTime
import sys

2.2 创建一个简单的 QTimeEdit

下面是一个简单的示例,展示如何创建和使用 QTimeEdit:

app = QApplication(sys.argv)
window = QWidget()
layout = QVBoxLayout()# 创建QTimeEdit实例
timeEdit = QTimeEdit()
timeEdit.setTime(QTime.currentTime())  # 设置当前时间
timeEdit.setDisplayFormat("HH:mm:ss")  # 设置显示格式label = QLabel(f"当前选择: {timeEdit.time().toString('HH:mm:ss')}")# 连接信号和槽
timeEdit.timeChanged.connect(lambda time: label.setText(f"当前选择: {time.toString('HH:mm:ss')}"))layout.addWidget(timeEdit)
layout.addWidget(label)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

2.3 常用属性和方法

2.3.1 时间设置
  • setTime(QTime): 设置时间
  • time(): 获取当前时间
  • setMinimumTime(QTime): 设置最小时间
  • setMaximumTime(QTime): 设置最大时间
  • setTimeRange(minTime, maxTime): 设置时间范围
2.3.2 显示格式
  • setDisplayFormat(format): 设置显示格式
    • 常用格式字符:
      • HH: 24 小时制小时 (00-23)
      • hh: 12 小时制小时 (01-12)
      • mm: 分钟 (00-59)
      • ss: 秒钟 (00-59)
      • AP/ap: 上午 / 下午标记
2.3.3 步进控制
  • setWrapping(True): 启用循环步进(到达最大 / 最小值时循环)
  • setSingleStep(seconds): 设置步进值(秒为单位)
2.3.4 信号
  • timeChanged(QTime): 当时间改变时发出
  • editingFinished(): 当编辑完成时发出(如按下 Enter 或失去焦点)

3. 进阶使用

3.1 设置不同的显示模式

# 24小时制,带秒
timeEdit.setDisplayFormat("HH:mm:ss")# 12小时制,带上午/下午标记
timeEdit.setDisplayFormat("hh:mm:ss AP")# 仅小时和分钟
timeEdit.setDisplayFormat("HH:mm")

3.2 限制时间范围

# 设置只能选择工作时间(9:00-18:00)
min_time = QTime(9, 0)
max_time = QTime(18, 0)
timeEdit.setTimeRange(min_time, max_time)

3.3 自定义步进值

# 设置每次点击箭头增加/减少15分钟
timeEdit.setSingleStep(15 * 60)  # 15分钟 = 900秒

3.4 处理信号和槽

def on_time_changed(time):print(f"时间已改变: {time.toString('HH:mm:ss')}")def on_editing_finished():print("编辑完成")timeEdit.timeChanged.connect(on_time_changed)
timeEdit.editingFinished.connect(on_editing_finished)

3.5 验证和转换时间

# 获取时间并转换为秒
current_time = timeEdit.time()
total_seconds = current_time.hour() * 3600 + current_time.minute() * 60 + current_time.second()# 从字符串设置时间
time_from_str = QTime.fromString("14:30:00", "HH:mm:ss")
timeEdit.setTime(time_from_str)

 3.6 与其他界面元素联动

1. 时间范围联动

场景:结束时间必须晚于开始时间。

实现方法:通过timeChanged信号连接到槽函数,动态调整另一个 QTimeEdit 的最小值。

from PyQt5.QtWidgets import QTimeEdit, QVBoxLayout, QWidget
from PyQt5.QtCore import QTimeclass TimeRangeDemo(QWidget):def __init__(self):super().__init__()layout = QVBoxLayout()# 开始时间选择器self.start_time = QTimeEdit()self.start_time.setDisplayFormat("HH:mm")self.start_time.setTime(QTime(9, 0))  # 默认9:00self.start_time.timeChanged.connect(self.update_end_time)# 结束时间选择器self.end_time = QTimeEdit()self.end_time.setDisplayFormat("HH:mm")self.end_time.setTime(QTime(18, 0))  # 默认18:00layout.addWidget(self.start_time)layout.addWidget(self.end_time)self.setLayout(layout)def update_end_time(self):"""当开始时间改变时,更新结束时间的最小值"""min_end_time = self.start_time.time().addSecs(3600)  # 至少1小时后self.end_time.setMinimumTime(min_end_time)

2. 倒计时计算联动

场景:根据选择的时间计算距离当前时间的倒计时。

实现方法:通过timeChanged信号连接到计算函数,并使用 QTimer 每秒更新显示。

from PyQt5.QtWidgets import QTimeEdit, QLabel, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtCore import QTime, QDateTime, QTimerclass CountdownDemo(QWidget):def __init__(self):super().__init__()layout = QVBoxLayout()# 目标时间选择器self.target_time = QTimeEdit()self.target_time.setDisplayFormat("HH:mm:ss")self.target_time.setTime(QTime.currentTime().addSecs(3600))  # 默认1小时后self.target_time.timeChanged.connect(self.update_countdown)# 倒计时显示self.countdown_label = QLabel("倒计时: 01:00:00")self.countdown_label.setStyleSheet("font-size: 24px;")# 开始/停止按钮self.start_btn = QPushButton("开始倒计时")self.start_btn.clicked.connect(self.toggle_countdown)# 定时器self.timer = QTimer(self)self.timer.timeout.connect(self.update_countdown)layout.addWidget(self.target_time)layout.addWidget(self.countdown_label)layout.addWidget(self.start_btn)self.setLayout(layout)self.countdown_active = Falsedef toggle_countdown(self):"""切换倒计时状态"""if self.countdown_active:self.timer.stop()self.start_btn.setText("开始倒计时")else:self.timer.start(1000)  # 每秒更新self.start_btn.setText("停止倒计时")self.countdown_active = not self.countdown_activedef update_countdown(self):"""更新倒计时显示"""current_time = QTime.currentTime()target_time = self.target_time.time()# 计算时间差(考虑跨天情况)if target_time < current_time:target_time = QTime(23, 59, 59).addSecs(target_time.secsTo(current_time) + 1)# 转换为QDateTime进行计算current_dt = QDateTime.currentDateTime()target_dt = QDateTime(current_dt.date(), target_time)if target_dt < current_dt:target_dt = target_dt.addDays(1)# 计算剩余秒数remaining_secs = current_dt.secsTo(target_dt)# 格式化为HH:MM:SShours = remaining_secs // 3600minutes = (remaining_secs % 3600) // 60seconds = remaining_secs % 60self.countdown_label.setText(f"倒计时: {hours:02d}:{minutes:02d}:{seconds:02d}")

3. 时间选择影响其他控件状态

场景:根据选择的时间启用 / 禁用其他控件。

实现方法:通过timeChanged信号连接到槽函数,修改其他控件的状态。

from PyQt5.QtWidgets import QTimeEdit, QPushButton, QLabel, QVBoxLayout, QWidget
from PyQt5.QtCore import QTimeclass ControlStatusDemo(QWidget):def __init__(self):super().__init__()layout = QVBoxLayout()# 时间选择器self.time_edit = QTimeEdit()self.time_edit.setDisplayFormat("HH:mm")self.time_edit.setTime(QTime(12, 0))  # 默认中午12点self.time_edit.timeChanged.connect(self.update_button_status)# 操作按钮self.action_btn = QPushButton("执行操作")self.action_btn.setEnabled(False)  # 默认禁用# 状态标签self.status_label = QLabel("请选择工作时间内的时间 (9:00-18:00)")layout.addWidget(self.time_edit)layout.addWidget(self.action_btn)layout.addWidget(self.status_label)self.setLayout(layout)def update_button_status(self):"""更新按钮状态"""selected_time = self.time_edit.time()min_time = QTime(9, 0)max_time = QTime(18, 0)if min_time <= selected_time <= max_time:self.action_btn.setEnabled(True)self.status_label.setText(f"已选择时间: {selected_time.toString('HH:mm')}")else:self.action_btn.setEnabled(False)self.status_label.setText("请选择工作时间内的时间 (9:00-18:00)")

4. 与 QSlider 联动调整时间

场景:使用滑块直观地调整时间。

实现方法:将 QSlider 的valueChanged信号连接到 QTimeEdit 的时间设置函数。

from PyQt5.QtWidgets import QTimeEdit, QSlider, QLabel, QVBoxLayout, QHBoxLayout, QWidget
from PyQt5.QtCore import Qt, QTimeclass TimeSliderDemo(QWidget):def __init__(self):super().__init__()layout = QVBoxLayout()# 时间选择器self.time_edit = QTimeEdit()self.time_edit.setDisplayFormat("HH:mm")self.time_edit.setTime(QTime(12, 0))  # 默认中午12点# 滑块(0-23小时)self.time_slider = QSlider(Qt.Horizontal)self.time_slider.setRange(0, 23)self.time_slider.setValue(12)  # 默认12点self.time_slider.valueChanged.connect(self.update_time)# 时间标签self.time_label = QLabel("当前时间: 12:00")# 连接反向更新self.time_edit.timeChanged.connect(self.update_slider)# 布局slider_layout = QHBoxLayout()slider_layout.addWidget(QLabel("0"))slider_layout.addWidget(self.time_slider)slider_layout.addWidget(QLabel("23"))layout.addWidget(self.time_edit)layout.addLayout(slider_layout)layout.addWidget(self.time_label)self.setLayout(layout)def update_time(self, value):"""根据滑块值更新时间"""hour = valuenew_time = QTime(hour, 0)self.time_edit.setTime(new_time)self.time_label.setText(f"当前时间: {new_time.toString('HH:mm')}")def update_slider(self):"""根据时间更新滑块值"""current_time = self.time_edit.time()self.time_slider.setValue(current_time.hour())self.time_label.setText(f"当前时间: {current_time.toString('HH:mm')}")

5. 与 QComboBox 联动选择预设时间

场景:通过下拉框选择预设的时间点。

实现方法:将 QComboBox 的currentIndexChanged信号连接到 QTimeEdit 的时间设置函数。

from PyQt5.QtWidgets import QTimeEdit, QComboBox, QVBoxLayout, QWidget
from PyQt5.QtCore import QTimeclass PresetTimeDemo(QWidget):def __init__(self):super().__init__()layout = QVBoxLayout()# 时间选择器self.time_edit = QTimeEdit()self.time_edit.setDisplayFormat("HH:mm")# 预设时间下拉框self.preset_combo = QComboBox()self.preset_combo.addItems(["早上 9:00","中午 12:00","下午 14:30","傍晚 18:00","晚上 20:00"])self.preset_combo.currentIndexChanged.connect(self.select_preset_time)# 设置初始值self.select_preset_time(0)layout.addWidget(self.preset_combo)layout.addWidget(self.time_edit)self.setLayout(layout)def select_preset_time(self, index):"""选择预设时间"""preset_times = [QTime(9, 0),QTime(12, 0),QTime(14, 30),QTime(18, 0),QTime(20, 0)]if 0 <= index < len(preset_times):self.time_edit.setTime(preset_times[index])

QTimeEdit 的联动核心是利用其信号(如timeChangededitingFinished)连接到自定义槽函数,在槽函数中实现对其他控件的操作。常见联动场景包括:

  1. 时间范围限制:通过setMinimumTime/setMaximumTime动态调整。
  2. 倒计时计算:结合 QTimer 实现实时更新。
  3. 控件状态控制:根据时间启用 / 禁用其他控件。
  4. 多控件协同:与 QSlider、QComboBox 等控件协同工作。
  5. 数据筛选:根据时间过滤表格、列表等数据。

4. 场景示例

4.1 会议时间选择器

class MeetingTimeSelector(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):layout = QVBoxLayout()self.timeEdit = QTimeEdit()self.timeEdit.setDisplayFormat("HH:mm")self.timeEdit.setTime(QTime(10, 0))  # 默认10:00# 设置工作时间范围min_time = QTime(9, 0)max_time = QTime(18, 0)self.timeEdit.setTimeRange(min_time, max_time)self.resultLabel = QLabel("请选择会议时间")self.timeEdit.timeChanged.connect(self.update_result)layout.addWidget(QLabel("选择会议时间:"))layout.addWidget(self.timeEdit)layout.addWidget(self.resultLabel)self.setLayout(layout)self.setWindowTitle('会议时间选择器')def update_result(self, time):self.resultLabel.setText(f"会议时间已设置为: {time.toString('HH:mm')}")

4.2 闹钟设置系统

class AlarmClock(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):layout = QVBoxLayout()# 闹钟时间选择self.alarmTimeEdit = QTimeEdit()self.alarmTimeEdit.setDisplayFormat("hh:mm:ss AP")self.alarmTimeEdit.setTime(QTime.currentTime().addSecs(60 * 60))  # 默认1小时后# 结果显示self.statusLabel = QLabel("闹钟未设置")# 按钮self.setButton = QPushButton("设置闹钟")self.setButton.clicked.connect(self.set_alarm)layout.addWidget(QLabel("设置闹钟时间:"))layout.addWidget(self.alarmTimeEdit)layout.addWidget(self.setButton)layout.addWidget(self.statusLabel)self.setLayout(layout)self.setWindowTitle('闹钟设置')def set_alarm(self):alarm_time = self.alarmTimeEdit.time()current_time = QTime.currentTime()# 计算闹钟响铃时间(考虑跨天情况)if alarm_time <= current_time:alarm_time = alarm_time.addSecs(24 * 3600)  # 加一天# 计算剩余时间(秒)seconds_left = current_time.secsTo(alarm_time)hours = seconds_left // 3600minutes = (seconds_left % 3600) // 60seconds = seconds_left % 60self.statusLabel.setText(f"闹钟已设置为 {alarm_time.toString('hh:mm:ss AP')}\n"f"将在 {hours} 小时 {minutes} 分钟 {seconds} 秒后响起")

4.3 工作时间计算器

class WorkTimeCalculator(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):layout = QVBoxLayout()# 开始时间self.startTimeEdit = QTimeEdit()self.startTimeEdit.setDisplayFormat("HH:mm")self.startTimeEdit.setTime(QTime(9, 0))# 结束时间self.endTimeEdit = QTimeEdit()self.endTimeEdit.setDisplayFormat("HH:mm")self.endTimeEdit.setTime(QTime(18, 0))# 结果显示self.resultLabel = QLabel("工作时长: 0小时0分钟")# 计算按钮self.calculateButton = QPushButton("计算工作时长")self.calculateButton.clicked.connect(self.calculate_work_time)# 连接信号self.startTimeEdit.timeChanged.connect(self.validate_times)self.endTimeEdit.timeChanged.connect(self.validate_times)layout.addWidget(QLabel("开始时间:"))layout.addWidget(self.startTimeEdit)layout.addWidget(QLabel("结束时间:"))layout.addWidget(self.endTimeEdit)layout.addWidget(self.calculateButton)layout.addWidget(self.resultLabel)self.setLayout(layout)self.setWindowTitle('工作时间计算器')def validate_times(self):"""确保结束时间晚于开始时间"""start_time = self.startTimeEdit.time()end_time = self.endTimeEdit.time()if end_time <= start_time:self.endTimeEdit.setTime(start_time.addSecs(3600))  # 默认加1小时def calculate_work_time(self):"""计算工作时长"""start_time = self.startTimeEdit.time()end_time = self.endTimeEdit.time()# 计算时间差(秒)seconds = start_time.secsTo(end_time)hours = seconds // 3600minutes = (seconds % 3600) // 60self.resultLabel.setText(f"工作时长: {hours}小时{minutes}分钟")

5. 常见问题解答

5.1 如何设置为 12 小时制?

timeEdit.setDisplayFormat("hh:mm:ss AP")

5.2 如何限制只能选择特定时间段?

min_time = QTime(9, 0)  # 9:00
max_time = QTime(18, 0)  # 18:00
timeEdit.setTimeRange(min_time, max_time)

5.3 如何获取用户选择的时间?

selected_time = timeEdit.time()  # 返回QTime对象

5.4 如何计算两个时间之间的差值?

time1 = QTime(9, 0)
time2 = QTime(12, 30)
seconds_diff = time1.secsTo(time2)  # 返回秒数差

5.5 如何设置步进值为 15 分钟?

timeEdit.setSingleStep(15 * 60)  # 15分钟 = 900秒

6. 完整代码演示

下面是一个完整的 PyQt5 应用程序,展示了 QTimeEdit 的各种使用场景。这个应用程序包含多个选项卡,每个选项卡演示了一个特定的使用场景:

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,QLabel, QDateTimeEdit, QDateEdit, QTimeEdit,QComboBox, QTabWidget, QPushButton, QMessageBox)
from PyQt5.QtCore import QDateTime, QDate, QTimeclass TimeEditDemo(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):# 创建主布局main_layout = QVBoxLayout()# 创建标签页控件tab_widget = QTabWidget()tab_widget.addTab(self.create_format_tab(), "格式设置")tab_widget.addTab(self.create_range_tab(), "范围设置")tab_widget.addTab(self.create_mode_tab(), "模式设置")main_layout.addWidget(tab_widget)self.setLayout(main_layout)self.setWindowTitle('QDateTimeEdit示例')self.setGeometry(300, 300, 600, 400)self.show()def create_format_tab(self):# 创建格式设置标签页tab = QWidget()layout = QVBoxLayout()# 创建日期时间编辑框self.datetime_edit = QDateTimeEdit()self.datetime_edit.setDateTime(QDateTime.currentDateTime())# 创建格式选择下拉框self.format_combo = QComboBox()self.format_combo.addItems(["yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm","dd.MM.yyyy HH:mm:ss","yyyy年MM月dd日 HH时mm分ss秒"])self.format_combo.currentTextChanged.connect(self.update_format)# 初始化格式self.update_format(self.format_combo.currentText())layout.addWidget(QLabel("选择日期时间格式:"))layout.addWidget(self.format_combo)layout.addWidget(QLabel("日期时间编辑框:"))layout.addWidget(self.datetime_edit)tab.setLayout(layout)return tabdef update_format(self, format_str):self.datetime_edit.setDisplayFormat(format_str)def create_range_tab(self):# 创建范围设置标签页tab = QWidget()layout = QVBoxLayout()# 创建日期时间编辑框self.range_edit = QDateTimeEdit()self.range_edit.setDateTime(QDateTime.currentDateTime())# 创建最小日期时间设置min_date_layout = QHBoxLayout()min_date_layout.addWidget(QLabel("最小日期时间:"))self.min_date_edit = QDateTimeEdit()self.min_date_edit.setDateTime(QDateTime.currentDateTime().addDays(-7))self.min_date_edit.dateTimeChanged.connect(self.update_min_date)min_date_layout.addWidget(self.min_date_edit)# 创建最大日期时间设置max_date_layout = QHBoxLayout()max_date_layout.addWidget(QLabel("最大日期时间:"))self.max_date_edit = QDateTimeEdit()self.max_date_edit.setDateTime(QDateTime.currentDateTime().addDays(7))self.max_date_edit.dateTimeChanged.connect(self.update_max_date)max_date_layout.addWidget(self.max_date_edit)# 初始化范围self.update_min_date(self.min_date_edit.dateTime())self.update_max_date(self.max_date_edit.dateTime())layout.addLayout(min_date_layout)layout.addLayout(max_date_layout)layout.addWidget(QLabel("日期时间编辑框:"))layout.addWidget(self.range_edit)tab.setLayout(layout)return tabdef update_min_date(self, date_time):self.range_edit.setMinimumDateTime(date_time)def update_max_date(self, date_time):self.range_edit.setMaximumDateTime(date_time)def create_mode_tab(self):# 创建模式设置标签页tab = QWidget()layout = QVBoxLayout()# 创建日期时间/日期/时间三种模式的编辑框self.datetime_mode_edit = QDateTimeEdit()self.datetime_mode_edit.setDateTime(QDateTime.currentDateTime())self.date_mode_edit = QDateEdit()self.date_mode_edit.setDate(QDate.currentDate())self.time_mode_edit = QTimeEdit()self.time_mode_edit.setTime(QTime.currentTime())# 设置显示格式self.datetime_mode_edit.setDisplayFormat("yyyy-MM-dd HH:mm:ss")self.date_mode_edit.setDisplayFormat("yyyy-MM-dd")self.time_mode_edit.setDisplayFormat("HH:mm:ss")# 添加日历弹出功能self.datetime_mode_edit.setCalendarPopup(True)self.date_mode_edit.setCalendarPopup(True)layout.addWidget(QLabel("日期时间模式:"))layout.addWidget(self.datetime_mode_edit)layout.addWidget(QLabel("日期模式:"))layout.addWidget(self.date_mode_edit)layout.addWidget(QLabel("时间模式:"))layout.addWidget(self.time_mode_edit)tab.setLayout(layout)return tabif __name__ == '__main__':app = QApplication(sys.argv)demo = TimeEditDemo()sys.exit(app.exec_())

 

这个应用程序包含五个选项卡,分别展示了 QTimeEdit 的不同使用场景:

  1. 会议时间:用户可以选择工作时间范围内的会议时间。
  2. 闹钟设置:设置闹钟时间并计算距离响铃的剩余时间。
  3. 工作时间:计算开始时间和结束时间之间的工作时长。
  4. 倒计时:设置并运行倒计时器,精确到秒。
  5. 格式设置:演示不同时间格式的显示效果。

每个场景都包含完整的用户交互和结果显示,可以直接运行代码查看效果,并根据需要进行修改和扩展。

http://www.dtcms.com/a/276093.html

相关文章:

  • Java中的wait和notify、Condition接口的使用
  • 分类问题与多层感知机
  • pip国内镜像源一览
  • [es自动化更新] Updatecli编排配置.yaml | dockerfilePath值文件.yml
  • springboot+swagger2文档从swagger-bootstrap-ui更换为knife4j及文档接口参数不显示问题
  • 【高等数学】第三章 微分中值定理与导数的应用——第七节 曲率
  • DirectX Repair修复工具下载,.NET修复,DirectX修复
  • python 中 ‘5‘ 和 5 有什么本质区别?
  • 【深度学习】 1 Deep Learning
  • 12. JVM的垃圾回收器
  • LangChain 代理(Agents)学习
  • 网页五子棋-对战
  • python学习打卡:DAY 37 早停策略和模型权重的保存
  • web网站无法抓包排查;burp无法抓包情况
  • comfyUI-controlNet-线稿软边缘
  • c++中的STL
  • Day59
  • 智能制造——解读50页智能工厂系统集成总体解决方案【附全文阅读】
  • python学习打卡:DAY 40 训练和测试的规范写法
  • 深入详解:决策树在医学影像领域心脏疾病诊断的应用及实现细节
  • 苦练Python第9天:if-else分支九剑
  • 影刀rpa初级选择题答案-02网页自动化-源码-初级证书
  • 6. JVM直接内存
  • 菜鸟的C#学习(二)
  • 动手开发 MCP Server (Datawhale AI夏令营)
  • TensorBoard
  • 全栈开发知识
  • 计算机毕业设计springboot阳阳助农电商平台 基于Spring Boot的阳阳助农电商平台设计与开发 Spring Boot框架下的阳阳助农电商平台构建
  • 苦练Python第7天:布尔七日斩
  • 模拟电路--供复习和嵌入式学习