Python-基于PyQt5,json和playsound的通用闹钟

前言:刚刚结束2024年秋季学期的学习,接下来我们继续来学习PyQt5。由于之前我们已经学习了PyQt5以及PyUIC,Pyrcc和QtDesigner的安装,配置。所以接下来我们一起深入PyQt5,学习如何利用PyQt5进行实际开发-基于PyQt5,json和playsound的通用闹钟。本次编程我们将会调用Python中的第三方库(如PyQt5playsound),大家需要提前下再好。此外我们也将会利用到Python的众多标准库实现整个程序的正常运行(如datetime,json,warning,sys等)。好,话不多说,我们直接开始今天的学习。

 第一步:导入库

我们需要sys,以便我们对PyCharm相关的操作和变量的访问。json,它提供了对JSON数据的编码和解码功能。接着我们导入标准库datetime。datetime类用于处理日期和时间(这个在后面的非重复,单日还是单周,月闹钟提醒设置里面非常重要),timedelta类用于表示时间间隔(这个为实现倒计时和设置计时功能提供了可能)。接下来是PyQt5的相关类和模块:QTimer类用于创建定时器;QTime类用于处理时间;QtWidgets模块包含了所有的GUI组件,如按钮、标签、文本框等;QIcon类用于创建图标。我们导入playsound函数用来播放音频文件(mp3格式的音频文件)。最后我们导入Python的标准库warnings来提供了对警告信息的控制(这里主要是我在后续调试代码过程中老是出现一些无关紧要的控制台警告,干脆保持静默得了)。

#导入必要库
import sys
import json
from datetime import datetime, timedelta
from PyQt5.QtCore import Qt, QTimer, QTime
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from playsound import playsound
import warnings

第二步:静默警告信息(禁用部分函数)

采用忽略警告的方式静默警告。

warnings.filterwarnings("ignore", category=DeprecationWarning)

第三步:搭建环境并创建闹钟类

这里我们需要保证解释器安装有必要的Python环境:1,PyQt5,playsound等。2, 准备铃声文件:alarm.mp3(这里我给大家介绍一款可录屏,录音的免费软件ocam,我的mp3文件就是用ocam制作的)。3,准备图标文件:alarm.png(这个也需要大家自行准备,png格式的闹钟图片,示例如下)

#闹钟类
class AdvancedAlarmClock(QMainWindow):def __init__(self):super().__init__()self.alarms = []self.timers = []self.current_alarm = Noneself.snooze_time = 5self.initUI()self.load_alarms()def initUI(self):self.setWindowTitle('高级闹钟')self.setGeometry(300, 300, 216, 286)self.setWindowIcon(QIcon('alarm.png'))# 主控件main_widget = QWidget()self.setCentralWidget(main_widget)layout = QVBoxLayout()# 闹钟设置区域alarm_setting = QGroupBox("新建闹钟")alarm_layout = QHBoxLayout()self.time_edit = QTimeEdit()self.time_edit.setDisplayFormat("HH:mm")alarm_layout.addWidget(self.time_edit)self.repeat_combo = QComboBox()self.repeat_combo.addItems(["不重复", "每天", "工作日", "周末", "自定义..."])alarm_layout.addWidget(self.repeat_combo)self.sound_combo = QComboBox()self.sound_combo.addItems(["默认铃声", "铃声1", "铃声2"])alarm_layout.addWidget(self.sound_combo)add_btn = QPushButton("添加闹钟")add_btn.clicked.connect(self.add_alarm)alarm_layout.addWidget(add_btn)alarm_setting.setLayout(alarm_layout)layout.addWidget(alarm_setting)# 闹钟列表self.alarm_list = QListWidget()layout.addWidget(self.alarm_list)# 控制按钮control_layout = QHBoxLayout()del_btn = QPushButton("删除闹钟")del_btn.clicked.connect(self.delete_alarm)control_layout.addWidget(del_btn)snooze_btn = QPushButton("贪睡 (%d分钟)" % self.snooze_time)snooze_btn.clicked.connect(self.snooze_alarm)control_layout.addWidget(snooze_btn)layout.addLayout(control_layout)# 倒计时和计时器timer_group = QGroupBox("计时功能")timer_layout = QHBoxLayout()self.countdown_spin = QSpinBox()self.countdown_spin.setRange(1, 120)self.countdown_spin.setSuffix(" 分钟")timer_layout.addWidget(self.countdown_spin)countdown_btn = QPushButton("开始倒计时")countdown_btn.clicked.connect(self.start_countdown)timer_layout.addWidget(countdown_btn)self.timer_label = QLabel("00:00:00")timer_layout.addWidget(self.timer_label)timer_btn = QPushButton("启动计时器")timer_btn.clicked.connect(self.start_timer)timer_layout.addWidget(timer_btn)timer_group.setLayout(timer_layout)layout.addWidget(timer_group)main_widget.setLayout(layout)# 定时检查闹钟self.check_timer = QTimer()self.check_timer.timeout.connect(self.check_alarms)self.check_timer.start(1000)  # 每秒检查一次def add_alarm(self):alarm_time = self.time_edit.time().toString("HH:mm")repeat_mode = self.repeat_combo.currentText()sound = self.sound_combo.currentText()alarm = {"time": alarm_time,"repeat": repeat_mode,"sound": sound,"enabled": True}self.alarms.append(alarm)self.update_alarm_list()self.save_alarms()def delete_alarm(self):selected = self.alarm_list.currentRow()if selected >= 0:del self.alarms[selected]self.update_alarm_list()self.save_alarms()def update_alarm_list(self):self.alarm_list.clear()for alarm in self.alarms:status = "✓" if alarm["enabled"] else "✗"item = QListWidgetItem(f"{alarm['time']} | {alarm['repeat']} | {alarm['sound']} {status}")self.alarm_list.addItem(item)def check_alarms(self):now = datetime.now().strftime("%H:%M")for alarm in self.alarms:if alarm["enabled"] and alarm["time"] == now:self.trigger_alarm(alarm)def trigger_alarm(self, alarm):self.current_alarm = alarmalarm["enabled"] = False# 播放声音try:playsound('alarm.mp3')except:pass# 显示窗口msg = QMessageBox()msg.setWindowTitle("闹钟提醒")msg.setText(f"时间到!当前时间 {alarm['time']}")msg.setStandardButtons(QMessageBox.Ok)msg.exec_()self.update_alarm_list()self.save_alarms()def snooze_alarm(self):if self.current_alarm:snooze_time = datetime.now() + timedelta(minutes=self.snooze_time)self.alarms.append({"time": snooze_time.strftime("%H:%M"),"repeat": "不重复","sound": self.current_alarm["sound"],"enabled": True})self.update_alarm_list()self.save_alarms()def start_countdown(self):minutes = self.countdown_spin.value()end_time = datetime.now() + timedelta(minutes=minutes)timer = QTimer()timer.timeout.connect(lambda: self.update_countdown(timer, end_time))timer.start(1000)self.timers.append(timer)def update_countdown(self, timer, end_time):remaining = end_time - datetime.now()if remaining.total_seconds() <= 0:timer.stop()self.timer_label.setText("00:00:00")playsound('alarm.mp3')else:self.timer_label.setText(str(remaining).split('.')[0])def start_timer(self):self.timer_start_time = datetime.now()timer = QTimer()timer.timeout.connect(self.update_timer)timer.start(1000)self.timers.append(timer)def update_timer(self):elapsed = datetime.now() - self.timer_start_timeself.timer_label.setText(str(elapsed).split('.')[0])def save_alarms(self):with open("alarms.json", "w") as f:json.dump(self.alarms, f)def load_alarms(self):try:with open("alarms.json", "r") as f:self.alarms = json.load(f)self.update_alarm_list()except:pass

第四步:创建驱动单元

最后,我们将会用一个初始化单元来驱动整个程序运行。

​
#驱动单元
if __name__ == '__main__':app = QApplication(sys.argv)clock = AdvancedAlarmClock()clock.show()sys.exit(app.exec_())

第五步:完整代码展示

#导入必要库
import sys
import json
from datetime import datetime, timedelta
from PyQt5.QtCore import Qt, QTimer, QTime
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from playsound import playsound
import warningswarnings.filterwarnings("ignore", category=DeprecationWarning)#闹钟类
class AdvancedAlarmClock(QMainWindow):def __init__(self):super().__init__()self.alarms = []self.timers = []self.current_alarm = Noneself.snooze_time = 5self.initUI()self.load_alarms()def initUI(self):self.setWindowTitle('高级闹钟')self.setGeometry(300, 300, 216, 286)self.setWindowIcon(QIcon('alarm.png'))# 主控件main_widget = QWidget()self.setCentralWidget(main_widget)layout = QVBoxLayout()# 闹钟设置区域alarm_setting = QGroupBox("新建闹钟")alarm_layout = QHBoxLayout()self.time_edit = QTimeEdit()self.time_edit.setDisplayFormat("HH:mm")alarm_layout.addWidget(self.time_edit)self.repeat_combo = QComboBox()self.repeat_combo.addItems(["不重复", "每天", "工作日", "周末", "自定义..."])alarm_layout.addWidget(self.repeat_combo)self.sound_combo = QComboBox()self.sound_combo.addItems(["默认铃声", "铃声1", "铃声2"])alarm_layout.addWidget(self.sound_combo)add_btn = QPushButton("添加闹钟")add_btn.clicked.connect(self.add_alarm)alarm_layout.addWidget(add_btn)alarm_setting.setLayout(alarm_layout)layout.addWidget(alarm_setting)# 闹钟列表self.alarm_list = QListWidget()layout.addWidget(self.alarm_list)# 控制按钮control_layout = QHBoxLayout()del_btn = QPushButton("删除闹钟")del_btn.clicked.connect(self.delete_alarm)control_layout.addWidget(del_btn)snooze_btn = QPushButton("贪睡 (%d分钟)" % self.snooze_time)snooze_btn.clicked.connect(self.snooze_alarm)control_layout.addWidget(snooze_btn)layout.addLayout(control_layout)# 倒计时和计时器timer_group = QGroupBox("计时功能")timer_layout = QHBoxLayout()self.countdown_spin = QSpinBox()self.countdown_spin.setRange(1, 120)self.countdown_spin.setSuffix(" 分钟")timer_layout.addWidget(self.countdown_spin)countdown_btn = QPushButton("开始倒计时")countdown_btn.clicked.connect(self.start_countdown)timer_layout.addWidget(countdown_btn)self.timer_label = QLabel("00:00:00")timer_layout.addWidget(self.timer_label)timer_btn = QPushButton("启动计时器")timer_btn.clicked.connect(self.start_timer)timer_layout.addWidget(timer_btn)timer_group.setLayout(timer_layout)layout.addWidget(timer_group)main_widget.setLayout(layout)# 定时检查闹钟self.check_timer = QTimer()self.check_timer.timeout.connect(self.check_alarms)self.check_timer.start(1000)  # 每秒检查一次def add_alarm(self):alarm_time = self.time_edit.time().toString("HH:mm")repeat_mode = self.repeat_combo.currentText()sound = self.sound_combo.currentText()alarm = {"time": alarm_time,"repeat": repeat_mode,"sound": sound,"enabled": True}self.alarms.append(alarm)self.update_alarm_list()self.save_alarms()def delete_alarm(self):selected = self.alarm_list.currentRow()if selected >= 0:del self.alarms[selected]self.update_alarm_list()self.save_alarms()def update_alarm_list(self):self.alarm_list.clear()for alarm in self.alarms:status = "✓" if alarm["enabled"] else "✗"item = QListWidgetItem(f"{alarm['time']} | {alarm['repeat']} | {alarm['sound']} {status}")self.alarm_list.addItem(item)def check_alarms(self):now = datetime.now().strftime("%H:%M")for alarm in self.alarms:if alarm["enabled"] and alarm["time"] == now:self.trigger_alarm(alarm)def trigger_alarm(self, alarm):self.current_alarm = alarmalarm["enabled"] = False# 播放声音try:playsound('alarm.mp3')except:pass# 显示窗口msg = QMessageBox()msg.setWindowTitle("闹钟提醒")msg.setText(f"时间到!当前时间 {alarm['time']}")msg.setStandardButtons(QMessageBox.Ok)msg.exec_()self.update_alarm_list()self.save_alarms()def snooze_alarm(self):if self.current_alarm:snooze_time = datetime.now() + timedelta(minutes=self.snooze_time)self.alarms.append({"time": snooze_time.strftime("%H:%M"),"repeat": "不重复","sound": self.current_alarm["sound"],"enabled": True})self.update_alarm_list()self.save_alarms()def start_countdown(self):minutes = self.countdown_spin.value()end_time = datetime.now() + timedelta(minutes=minutes)timer = QTimer()timer.timeout.connect(lambda: self.update_countdown(timer, end_time))timer.start(1000)self.timers.append(timer)def update_countdown(self, timer, end_time):remaining = end_time - datetime.now()if remaining.total_seconds() <= 0:timer.stop()self.timer_label.setText("00:00:00")playsound('alarm.mp3')else:self.timer_label.setText(str(remaining).split('.')[0])def start_timer(self):self.timer_start_time = datetime.now()timer = QTimer()timer.timeout.connect(self.update_timer)timer.start(1000)self.timers.append(timer)def update_timer(self):elapsed = datetime.now() - self.timer_start_timeself.timer_label.setText(str(elapsed).split('.')[0])def save_alarms(self):with open("alarms.json", "w") as f:json.dump(self.alarms, f)def load_alarms(self):try:with open("alarms.json", "r") as f:self.alarms = json.load(f)self.update_alarm_list()except:pass#驱动单元
if __name__ == '__main__':app = QApplication(sys.argv)clock = AdvancedAlarmClock()clock.show()sys.exit(app.exec_())

 第六步:操作指南 

1.设置新闹钟:
     - 选择时间
     - 设置重复模式
     - 选择铃声
     - 点击"添加闹钟" 
2.管理闹钟:
     - 双击列表项启用/禁用
     - 选择后点击"删除闹钟"
     - 响铃时点击"贪睡"延迟提醒
 3.计时工具**:
     - 倒计时:设置分钟数 → 开始倒计时
     - 秒表:直接启动计时器

第七步:运行效果展示

正常状态:

最大化:

最小化:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8911.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构课程设计(三)构建决策树

3 决策树 3.1 需求规格说明 【问题描述】 ID3算法是一种贪心算法&#xff0c;用来构造决策树。ID3算法起源于概念学习系统&#xff08;CLS&#xff09;&#xff0c;以信息熵的下降速度为选取测试属性的标准&#xff0c;即在每个节点选取还尚未被用来划分的具有最高信息增益的…

2024收尾工作

目录 开场白 栈与队列 LeetCode232. 用栈实现队列 LeetCode225. 用队列实现栈 LeetCode102. 二叉树的层序遍历 LeetCode103. 二叉树的锯齿形层序遍历 堆&#xff08;优先级队列&#xff09; 堆排序 LeetCode215. 数组中的第 k 个最大元素 总结 开场白 今天是除夕&…

纯css实现div宽度可调整

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>纯css实现div尺寸可调整</title><style…

浅谈Linux的发展

目录 1.Linux背景 1.1 发展史 UNIX发展的历史 1.2开源 1.3官网 1.4.企业应用现状 1.5.发行版本 1.6 os概念&#xff0c;定位 1.Linux背景 1.1 发展史 学习Linux系统编程&#xff0c;你可能要问Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展史…

四层网络模型

互联网由终端主机、链路和路由器组成&#xff0c;数据通过逐跳的方式&#xff0c;依次经过每条链路进行传输。 网络层的工作是将数据包从源端到目的端&#xff0c;跨越整个互联网。 网络层的数据包称为数据报。网络将数据报交给链路层&#xff0c;指示它通过第一条链路发送数据…

世上本没有路,只有“场”et“Bravo”

楔子&#xff1a;电气本科“工程电磁场”电气研究生课程“高等电磁场分析”和“电磁兼容”自学”天线“、“通信原理”、“射频电路”、“微波理论”等课程 文章目录 前言零、学习历程一、Maxwells equations1.James Clerk Maxwell2.自由空间中传播的电磁波3.边界条件和有限时域…

python学opencv|读取图像(四十六)使用cv2.bitwise_or()函数实现图像按位或运算

【0】基础定义 按位与运算&#xff1a;全1取1&#xff0c;其余取0。按位或运算&#xff1a;全0取0&#xff0c;其余取1。 【1】引言 前序学习进程中&#xff0c;已经对图像按位与计算进行了详细探究&#xff0c;相关文章链接如下&#xff1a; python学opencv|读取图像&…

如何把obsidian的md文档导出成图片,并加上文档属性

上篇关于这个插件PKMer_Obsidian 插件&#xff1a;Export Image plugin 一键将笔记转换为图片分享的文章 如何把obsidian的md文档导出成图片&#xff0c;并加上水印-CSDN博客 如何导出图片的时候让文档属性也显示出来&#xff0c;啊啊&#xff0c;这个功能找了一晚上&#xf…

MATLAB算法实战应用案例精讲-【数模应用】方向梯度直方图(HOG)(附python代码实现)

目录 前言 算法原理 特征描述 什么是方向梯度直方图? 算法思想: 实现方法: 性能提高: HOG特征提取 直方图阈值化 直方图均衡化 算法步骤: 算法流程 1. 图像预处理 2. 计算图像梯度 3. 计算梯度直方图 4. 图像HOG特征向量 直方图反向投影 其它类型图像直…

CycleGAN模型解读(附源码+论文)

CycleGAN 论文链接&#xff1a;Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks 官方链接&#xff1a;pytorch-CycleGAN-and-pix2pix 老规矩&#xff0c;先看看效果 总体流程 先简单过一遍流程&#xff0c;细节在代码里说。CycleGAN有…

ue5 GAS制作一个技能,技能冷却,给剑添加碰撞预设,打击敌人

总结&#xff1a; 新建文件夹 ability 取名BP_BaseAbility 新建一个技能GAB_Melee 上面技能GAB_Melee和技能基类BP_BaseAbility 进入技能GAB_Melee&#xff0c;添加打印火云掌 给这个技能添加标签 点这个号 这样命名&#xff0c;小心这个点&#xff08;.&#xff09…

工作总结:git篇

文章目录 前言基础Gerrit1.克隆2.新建本地分支和checkout3.添加到暂存区新增文件到暂存区修改已经添加到暂存区的文件取消添加到暂存区的文件 4.提交到本地仓库在不重复提交的情况下&#xff0c;修改本次提交 5.提交到远程仓库6.评审其他辅助命令 前言 目前也算是工作一段时间…

ESP32 I2S音频总线学习笔记(二):I2S读取INMP441音频数据

简介 在这个系列的上一篇文章中&#xff0c;我们介绍了ESP32 I2S音频总线的相关知识&#xff0c;简要了解了什么是I2S总线、它的通信格式&#xff0c;以及相关的底层API函数。没有看过上篇文章的可以点击文章进行回顾&#xff1a; ESP32 I2S音频总线学习笔记&#xff08;一&a…

(学习总结21)C++11 异常与智能指针

C11 异常与智能指针 异常异常的概念异常的抛出和捕获栈展开查找匹配的处理代码异常重新抛出异常安全问题异常规范标准库的异常 智能指针RAII 和智能指针的设计思路智能指针的使用场景分析C标准库智能指针的使用weak_ptr 和 shared_ptr循环引用weak_ptrshared_ptr 循环引用问题 …

智能调度体系与自动驾驶技术优化运输配送效率的研究——兼论开源AI智能名片2+1链动模式S2B2C商城小程序的应用潜力

摘要&#xff1a;随着全球化和数字化进程的加速&#xff0c;消费者需求日益呈现出碎片化和个性化的趋势&#xff0c;这对物流运输行业提出了前所未有的挑战。传统的物流调度体系与调度方式已难以满足当前复杂多变的物流需求&#xff0c;因此&#xff0c;物流企业必须积极引入大…

AndroidCompose Navigation导航精通1-基本页面导航与ViewPager

文章目录 前言基本页面导航库依赖导航核心部件简单NavHost实现ViewPagerPager切换逻辑图阐述Pager导航实战前言 在当今的移动应用开发中,导航是用户与应用交互的核心环节。随着 Android Compose 的兴起,它为开发者提供了一种全新的、声明式的方式来构建用户界面,同时也带来…

noteboolm 使用笔记

今天心血来潮&#xff0c;想要体验下AInotebook&#xff0c;看看最新的软件能够做到什么程度。 于是来到了notebooklm&#xff0c;这是一个google推出的AI笔记本的网站&#xff0c;我想知道我们能在上面做一些怎么样有趣的事情&#xff01; 网址&#xff1a;https://notebookl…

JAVA 接口、抽象类的关系和用处 详细解析

接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口&#xff0c;可以只选择实现接口中的 部分方法&#xff08;所有的方法都要有&#xff0c;可以一部分已经写具体&#xff0c;另一部分继续保留抽象&#xff09;&#xff0c;原因在于&#xff1a; 抽象类本身…

ReactNative react-devtools 夜神模拟器连调

目录 一、安装react-devtools 二、在package.json中配置启动项 三、联动 一、安装react-devtools yarn add react-devtools5.3.1 -D 这里选择5.3.1版本&#xff0c;因为高版本可能与夜神模拟器无法联动&#xff0c;导致部分功能无法正常使用。 二、在package.json中配置启…

关于使用Mybatis-plus的TableNameHandler动态表名处理器实现分表业务的详细介绍

引言 随着互联网应用的快速发展&#xff0c;数据量呈爆炸式增长。传统的单表设计在面对海量数据时显得力不从心&#xff0c;容易出现性能瓶颈、查询效率低下等问题。为了提高数据库的扩展性和响应速度&#xff0c;分表&#xff08;Sharding&#xff09;成为了一种常见的解决方案…