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

news2025/1/31 6:36:05

前言:刚刚结束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 = None
        self.snooze_time = 5
        self.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 = alarm
        alarm["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_time
        self.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 warnings

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

#闹钟类
class AdvancedAlarmClock(QMainWindow):
    def __init__(self):
        super().__init__()
        self.alarms = []
        self.timers = []
        self.current_alarm = None
        self.snooze_time = 5
        self.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 = alarm
        alarm["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_time
        self.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.coloradmin.cn/o/2285250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于数字地DGND和模拟地AGND隔离

文章目录 前言一、1、为什么要进行数字地和模拟地隔离二、隔离元件1.①0Ω电阻&#xff1a;2.②磁珠&#xff1a;3.电容&#xff1a;4.④电感&#xff1a; 三、隔离方法①单点接地②数字地与模拟地分开布线&#xff0c;最后再PCB板上一点接到电源。③电源隔离④、其他隔离方法 …

DeepSeek R1学习

0.回顾&#xff1a; https://blog.csdn.net/Together_CZ/article/details/144431432?ops_request_misc%257B%2522request%255Fid%2522%253A%25226574a586f0850d0329fbb720e5b8d5a9%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id…

12 款开源OCR发 PDF 识别框架

2024 年 12 款开源文档解析框架的选型对比评测&#xff1a;PDF解析、OCR识别功能解读、应用场景分析及优缺点比较 这是该系列的第二篇文章&#xff0c;聚焦于智能文档处理&#xff08;特别是 PDF 解析&#xff09;。无论是在模型预训练的数据收集阶段&#xff0c;还是基于 RAG…

【反悔堆】【hard】力扣871. 最低加油次数

汽车从起点出发驶向目的地&#xff0c;该目的地位于出发位置东面 target 英里处。 沿途有加油站&#xff0c;用数组 stations 表示。其中 stations[i] [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处&#xff0c;并且有 fueli 升汽油。 假设汽车油…

为什么应用程序是特定于操作系统的?[计算机原理]

你把WINDOWS程序复制到MAC上使用&#xff0c;会发现无法运行。你可能会说&#xff0c;MAC是arm处理器&#xff0c;而WINDWOS是X86 处理器。但是在2019年&#xff0c;那时候MAC电脑还全是Intel处理器&#xff0c;在同样的X86芯片上&#xff0c;运行MAC和WINDOWS 程序还是无法互相…

多项日常使用测试,带你了解如何选择AI工具 Deepseek VS ChatGpt VS Claude

多项日常使用测试&#xff0c;带你了解如何选择AI工具 Deepseek VS ChatGpt VS Claude 注&#xff1a;因为考虑到绝大部分人的使用&#xff0c;我这里所用的模型均为免费模型。官方可访问的。ChatGPT这里用的是4o Ai对话&#xff0c;编程一直以来都是人们所讨论的话题。Ai的出现…

什么是循环神经网络?

一、概念 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一类用于处理序列数据的神经网络。与传统的前馈神经网络不同&#xff0c;RNN具有循环连接&#xff0c;可以利用序列数据的时间依赖性。正因如此&#xff0c;RNN在自然语言处理、时间序列预测、语…

Flink运行时架构

一、系统架构 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager是一个Flink集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。也就是说&#xff0c;每个应用都应该被唯一的JobManager所控制执行。 JobManger又包含3个不同的组件。 &am…

网络工程师 (6)操作系统概述

一、操作系统的定义 &#xff08;一&#xff09;基本定义 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;是计算机系统中至关重要的基础性系统软件。它是计算机硬件与上层软件之间的桥梁&#xff0c;负责管理和控制整个计算机系统的硬件和软件资源&…

【2025年数学建模美赛C题】第1-5问F奖解题思路+高级绘图+可运行代码

基于多模型分析的奥运会奖牌预测与影响因素研究 解题思路一、问题重述二、问题分析三、模型假设与符号说明四、数据预处理五、奖牌榜预测5.1 基于LSTM长短期记忆循环神经网络的预测模型的建立5.2 模型预测结果 六、首枚奖牌预测6.1 BP神经网络的建立6.2 模型预测结果 七、各国奖…

RoboMaster- RDK X5能量机关实现案例(一)识别

作者&#xff1a;SkyXZ CSDN&#xff1a;https://blog.csdn.net/xiongqi123123 博客园&#xff1a;https://www.cnblogs.com/SkyXZ 在RoboMaster的25赛季&#xff0c;我主要负责了能量机关的视觉方案开发&#xff0c;目前整体算法已经搭建完成&#xff0c;实际方案上我使用的上…

检测到联想鼠标自动调出运行窗口,鼠标自己作为键盘操作

联想鼠标会自动时不时的调用“运行”窗口 然后鼠标自己作为键盘输入 然后打开这个网页 &#xff08;不是点击了什么鼠标外加按键&#xff0c;这个鼠标除了左右和中间滚轮&#xff0c;没有其他按键了&#xff09;

星火大模型接入及文本生成HTTP流式、非流式接口(JAVA)

文章目录 一、接入星火大模型二、基于JAVA实现HTTP非流式接口1.配置2.接口实现&#xff08;1&#xff09;分析接口请求&#xff08;2&#xff09;代码实现 3.功能测试&#xff08;1&#xff09;测试对话功能&#xff08;2&#xff09;测试记住上下文功能 三、基于JAVA实现HTTP流…

如何将电脑桌面默认的C盘设置到D盘?详细操作步骤!

将电脑桌面默认的C盘设置到D盘的详细操作步骤&#xff01; 本博文介绍如何将电脑桌面&#xff08;默认为C盘&#xff09;设置在D盘下。 首先&#xff0c;在D盘建立文件夹Desktop&#xff0c;完整的路径为D:\Desktop。winR&#xff0c;输入Regedit命令。&#xff08;或者单击【…

java 判断Date是上午还是下午

我要用Java生成表格统计信息&#xff0c;如下图所示&#xff1a; 所以就诞生了本文的内容。 在 Java 里&#xff0c;判断 Date 对象代表的时间是上午还是下午有多种方式&#xff0c;下面为你详细介绍不同的实现方法。 方式一&#xff1a;使用 java.util.Calendar Calendar 类…

C语言------数组从入门到精通

1.一维数组 目标:通过思维导图了解学习一维数组的核心知识点: 1.1定义 使用 类型名 数组名[数组长度]; 定义数组。 // 示例&#xff1a; int arr[5]; 1.2一维数组初始化 数组的初始化可以分为静态初始化和动态初始化两种方式。 它们的主要区别在于初始化的时机和内存分配的方…

FLTK - FLTK1.4.1 - 搭建模板,将FLTK自带的实现搬过来做实验

文章目录 FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验概述笔记my_fltk_test.cppfltk_test.hfltk_test.cxx用adjuster工程试了一下&#xff0c;好使。END FLTK - FLTK1.4.1 - 搭建模板&#xff0c;将FLTK自带的实现搬过来做实验 概述 用fluid搭建UI…

DeepSeek学术写作测评第二弹:数据分析、图表解读,效果怎么样?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 针对最近全球热议的DeepSeek开源大模型&#xff0c;娜姐昨天分析了关于论文润色、中译英的详细效果测评&#xff1a; DeepSeek学术写作测评第一弹&#xff1a;论文润色&#…

Direct2D 极速教程(2) —— 画淳平

极速导航 创建新项目&#xff1a;002-DrawJunpeiWIC 是什么用 WIC 加载图片画淳平 创建新项目&#xff1a;002-DrawJunpei 右键解决方案 -> 添加 -> 新建项目 选择"空项目"&#xff0c;项目名称为 “002-DrawJunpei”&#xff0c;然后按"创建" 将 “…

在win11系统笔记本中使用Ollama部署deepseek制作一个本地AI小助手!原来如此简单!!!

大家新年好啊&#xff0c;明天就是蛇年啦&#xff0c;蛇年快乐&#xff01; 最近DeepSeek真的太火了&#xff0c;我也跟随B站&#xff0c;使用Ollama在一台Win11系统的笔记本电脑部署了DeepSeek。由于我的云服务器性能很差&#xff0c;虽然笔记本的性能也一般&#xff0c;但是…