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

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 = 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.kler.cn/a/522960.html

相关文章:

  • 构建 QA 系统:基于文档和模型的问答
  • 2218. 从栈中取出 K 个硬币的最大面值和
  • docker 学习笔记
  • 知识库建设对提升团队协作与创新能力的影响分析
  • Padas进行MongoDB数据库CRUD
  • 算法题(48):反转链表
  • 汉语向编程指南
  • LeetCode:62.不同路径
  • 开发者交流平台项目部署到阿里云服务器教程
  • 【Redis】hash 类型的介绍和常用命令
  • 编解码技术:最大秩距离码(Maximum Rank Distance Code)
  • 代码随想录刷题day18|(哈希表篇)01.两数之和
  • QT:图像上绘制图形
  • 基于Django的个人博客系统的设计与实现
  • 【现代深度学习技术】深度学习计算 | 参数管理
  • Flink (十三) :Table API 与 DataStream API 的转换 (一)
  • TypeScript 学习 -类型 - 9
  • MySQL知识点总结(十二)
  • 树和图的实现与应用:C语言实践详解
  • Docker/K8S
  • C语言中的do……while和while循环有什么区别?
  • MySQL事物,MVCC机制
  • 【搜索回溯算法篇】:多源BFS--从简单BFS到多点协同,探索搜索算法的进化
  • 挂载mount
  • 可扩展架构:如何打造一个善变的柔性系统?
  • LTV预估 | 多视角对比学习框架CMLTV