【python小项目】用python写一个小工具——番茄钟

news2024/12/25 0:21:12

用python写一个小工具——番茄钟

最近听到朋友说在用番茄钟,有点兴趣也想下载一个来用用,后面仔细一想这玩意做起来也不难,索性自己顺手写一个算了,在这里也分享给大家了

一、功能简述

番茄钟即番茄工作法,番茄工作法是简单易行的时间管理工具,使用番茄工作法即一个番茄时间共30分钟,25分钟工作,5分钟休息;

特点一:番茄时长有三档

因为这个工具本人也是考虑到每个人情况不一样,不一定25分钟就适合自己,所以将番茄钟时长设为30min/45min/60min三档,自由选择

特点二:番茄统计功能

特点三:休息期间会自动播放放松音乐,当然不喜欢也支持禁止播放放松音乐,休息时间结束后,音乐也会自动停止(意味着又要开始“搬砖”了)

特点四:番茄钟结束后,会有蜂鸣音提示,并且跳出弹框

番茄钟界面

二、使用到的主要模块

tkinter:用于界面设计

winsound:用于调用蜂鸣器提示音

pygame:用于音乐播放

time:时间相关的格式转换

三、核心模块代码分析

代码的主要思路是主函数中,利用tkinter模块布局界面、按钮、标签等组件,然后将番茄钟、休息两大核心功能封装到函数中,一旦点击对应的按钮,即开启一个新线程用于执行对应的功能,同时通过全局变量thread_flag来保持永远只有主线程和功能线程2个线程,避免多次点击,产生多个线程同时运行,造成番茄钟混乱;

1、番茄钟模块
## 创建番茄计时函数
def tomato_clock(remain_time):    
    # 如果在休息时间未结束就开启番茄钟,则停止音乐
    pygame.mixer.music.pause()
    
    # 用来提醒用户选择番茄钟时长,为选择的话,就跳出函数,结束线程
    if remain_time == 0:
        lb3.configure(text='请先选择番茄钟时长')
        return
    print(remain_time)
    
    # gmtime这里是将时间转化为计算机可处理的时间格式即time_t到tm类型的转换;不是重点,知道是格式转化即可
    # strptime()函数将字符串转换为datetime
    begin_time = time.strftime('%M:%S', time.gmtime(remain_time))
    
    # 将时间内容打印到界面上
    lb2.configure(text=begin_time)
    lb3.configure(text='总时间/剩余时间')
    
    # 用于保证番茄钟线程或者休息线程只有一个能存在,这个也是本人觉得比较巧的一个点
    global thread_flag
    if thread_flag:
        thread_flag = False
    else:
        thread_flag = True
    tmp_thread_flag = thread_flag
    
    # 时间变化部分
    for i in range(remain_time):
        # 如果收到休息线程导致的thread_flag标志位的变化,则退出线程
        if tmp_thread_flag != thread_flag:
            return
        
        remain_time -= 1
        remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time))
        
        # 将时钟实时更新到界面上
        lb1.configure(text=remain_time_str)
        root.update()
        time.sleep(1)
        
        #时间到了,开启蜂鸣提醒与提示框提醒
        if remain_time == 0:
            Beep(500, 800)
            tomato_count()
            mymsg()
    lb1.configure(text=begin_time)
    
    #使用者确认后,自动进入休息模式
    relax()
2、音乐控制函数
# 音乐控制函数,用来控制是否允许休息时播放音乐,其实本质只是静音而已,狗头.jpg
# 在定义时,music_flag已经初始化True,代表运行休息时播放音乐
def music_allow():
    global music_flag		#声明全局变量
    # 如果已经是True(即不禁止音乐时),勾选了按钮,则music_flag 变为 False,禁止音乐
    if music_flag:
        music_flag = False
        pygame.mixer.music.set_volume(0.0)
    else:
        # 代表取消勾选,不禁止音乐
        music_flag = True
        pygame.mixer.music.set_volume(0.5)
3、main中的按钮部分
# 每当按钮点击后,就会产生一个线程,执行对应的功能,和主线程并行
# 以防止单线程的话,进入番茄钟或者休息时,界面中的其他功能按钮失效

# 开启番茄钟按钮,使用lambda构造匿名函数是因为command后接的函数如果有参数会失效,这点本人也不清楚,没去深究,直接匿名函数走去
# 同时daemon=True,即将线程设为守护线程,解决主线程退出时,其他线程不正常退出的问题
Button1 = tk.Button(root, text='开启一个番茄', bg='orange', fg='black', font='Verdana 13 bold',width=15,
    height=1, command=lambda: threading.Thread(target=tomato_clock, daemon=True,args=(var.get(),)).start())
Button1.place(x=70, y=150)

# 休息一下按钮
Button2 = tk.Button(root, text='休息一下', bg='cornflowerblue', fg='black', font='Verdana 13 bold',
                        width=15,height=1,command=lambda:threading.Thread(target=relax,daemon=True).start())
Button2.place(x=70, y=200)

四、整体代码

# -*- coding:utf-8 -*-
import tkinter as tk
import tkinter.messagebox
from winsound import Beep
import threading
import sys
import pygame
import time

# 用于统计完成的番茄钟个数
count = 0
# 线程切换标志
thread_flag = True
# 音乐开关标志
music_flag = True

# 调用Tk()创建主窗口
root = tk.Tk()
# 给主窗口起一个名字,也就是窗口的名字
root.title('Rio的番茄钟')
# 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
root.geometry('460x300')
root.configure(bg='Tomato')


# 创建完成计时后的弹窗
def mymsg():
    try:
        tk.messagebox.showinfo("提示", "恭喜完成一个番茄钟!!记得休息一下")
    except Exception as e:
        print(type(e), e)
        sys.exit()

# 休息结束弹窗
def mymsg2():
    tk.messagebox.showinfo("提示", "休息完毕!")

# 创建番茄计时函数
# strptime()函数将字符串转换为datetime
def tomato_clock(remain_time):
    # 如果在休息时间未结束就开启番茄钟,则停止音乐
    pygame.mixer.music.pause()
    # 避免未进行番茄钟时长选择
    if remain_time == 0:
        lb3.configure(text='请先选择番茄钟时长')
        return
    print(remain_time)
    begin_time = time.strftime('%M:%S', time.gmtime(remain_time))
    lb2.configure(text=begin_time)
    lb3.configure(text='总时间/剩余时间')
    global thread_flag
    if thread_flag:
        thread_flag = False
    else:
        thread_flag = True
    tmp_thread_flag = thread_flag
    for i in range(remain_time):
        if tmp_thread_flag != thread_flag:
            return
        remain_time -= 1
        remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time))
        lb1.configure(text=remain_time_str)
        root.update()
        time.sleep(1)
        if remain_time == 0:
            Beep(500, 800)
            tomato_count()
            mymsg()
    lb1.configure(text=begin_time)
    relax()


# 创建番茄计数的函数
def tomato_count():
    global count
    count += 1
    lb4.configure(text=count)

# 创建休息时间函数
def relax():
    remain_time = 480   # 休息8分钟
    begin_time = time.strftime('%M:%S', time.gmtime(remain_time))
    lb2.configure(text=begin_time)
    lb3.configure(text='总时间/剩余时间')

    # 线程标志,用于结束旧线程
    global thread_flag
    if thread_flag:
        thread_flag = False
    else:
        thread_flag = True
    tmp_thread_flag = thread_flag
    pygame.mixer.music.play(-1)
    for i in range(remain_time):
        if tmp_thread_flag != thread_flag:
            return
        remain_time -= 1
        remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time))
        lb1.configure(text=remain_time_str)
        root.update()
        time.sleep(1)
        if remain_time == 0:
            pygame.mixer.music.pause()
            mymsg2()
    lb1.configure(text=begin_time)

# 音乐控制函数
def music_allow():
    global music_flag
    # 如果已经是True(即不禁止音乐时),勾选了按钮,则music_flag 变为 False,禁止音乐
    if music_flag:
        music_flag = False
        pygame.mixer.music.set_volume(0.0)
    else:
        music_flag = True
        pygame.mixer.music.set_volume(0.5)

if __name__ == "__main__":

    #音乐初始化
    pygame.mixer.init()
    # 异常抛出,防止没有放音乐文件
    try:
        pygame.mixer.music.load('music.mp3')
    except Exception as e:
        print(type(e), e)
        tk.messagebox.showinfo("提示", "无文件music.mp3或改文件路径不对")
        sys.exit()
    pygame.mixer.music.set_volume(0.5)
    # 创建变量
    var = tk.IntVar()
    # 给变量赋初值为30
    var.set(30)

    # 番茄动态计时
    lb1 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=7, height=1)
    lb1.place(x=130, y=100)

    # 番茄固定时间
    lb2 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=5, height=1)
    lb2.place(x=60, y=100)

    # 剩余时间/总时间
    lb3 = tk.Label(root, text=' ', bg='Tomato', fg='white', font='Verdana 16 bold', width=14, height=2)
    lb3.place(x=50, y=44)

    # 番茄个数显示
    lb4 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=7, height=1)
    lb4.place(x=90, y=20)

    # 左上角的 番茄:
    lb5 = tk.Label(root, text='已积累番茄:', bg='Tomato', fg='white', font='Verdana 16 bold', width=8, height=1)
    lb5.place(x=5, y=20)

    # 按钮
    ##创造一个frame来收纳按钮
    fr1 = tk.LabelFrame(root,bg='LightGreen',text='选择番茄钟时长', relief='groove', bd=1,)
    fr1.pack(side='right')
    r1 = tk.Radiobutton(fr1, text='30min', variable=var, bg='LightGreen', value=1800)
    r1.pack()
    r2 = tk.Radiobutton(fr1, text='45min', variable=var, bg='LightGreen', value=2700)
    r2.pack()
    r3 = tk.Radiobutton(fr1, text='60min', variable=var, bg='LightGreen', value=3599)
    r3.pack()
    Checkbutton = tk.Checkbutton(fr1, text="是否禁止音乐", fg='black', bg='LightGreen', command=music_allow)
    Checkbutton.pack()

    # 开启一个番茄
    #利用多线程,避免进入番茄钟后,退出按钮失效
    Button1 = tk.Button(root, text='开启一个番茄', bg='orange', fg='black', font='Verdana 13 bold',width=15,
                      height=1, command=lambda: threading.Thread(target=tomato_clock, daemon=True,args=(var.get(),)).start())
    Button1.place(x=70, y=150)

    # 休息一下
    Button2 = tk.Button(root, text='休息一下', bg='cornflowerblue', fg='black', font='Verdana 13 bold',
                        width=15, height=1, command=lambda: threading.Thread(target=relax, daemon=True).start())
    Button2.place(x=70, y=200)

    # 添加按钮,以及按钮的文本,并通过command 参数设置关闭窗口的功能
    button = tk.Button(root, text="退出", fg='black', bg='YellowGreen', width=15, command=root.quit)
    # 将按钮放置在主窗口内
    button.place(x=105, y=250)

    #开启主循环,让窗口处于显示状态
    root.mainloop()

最后

当然这个项目也不是完全从0开始,有借鉴了python 用tkinter 做一个简易番茄钟的代码,其实本人更多的是丰富和优化。也欢迎大家在我写的部分继续优化丰富;也欢迎大家批评正。

我也将代码以及生成的.exe文件打包成压缩包上传了,用python写一个小工具-番茄钟可以直接下载使用该工具,有需要可自行下载,.exe文件在压缩包的dist文件夹中,感谢支持

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

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

相关文章

产品经理必备的能力有哪些?

从一名普通的产品经理到一名优秀的产品经理要经历什么?哪些又是产品经理必备的能力?产品经理对能力的需求也不尽相同,在不同的团队合作模式下,还必须懂得各种能力。 一、业务分析能力 数据分析能力该是什么样的呢 1、有数据意识…

indexDB 本地数据库

indexDB 本地数据库 IndexedDB是一种使用浏览器存储大量数据的方法,它创造的数据可以被查询,并且可以离线使用。 优点:空间大小,大于250M;支持二进制:IndexedDB不但可以存储对象,字符串等&#…

利用MS11_003 IE漏洞攻击win7主机

利用MS11_003 IE漏洞攻击win7主机 微软2011年2月9日发布12个安全补丁,其中3个最高级别为严重等级,9个为重要等级,共计修复了影响 Windows、Office、IE 和 IIS 的22个漏洞。 MS11-003、MS11-006 和 MS11-007 为严重等级,需要优先部署。其中,MS11-003 的最高利用指数为1它修…

基于web的课程管理系统设计与实现(java+SqlServer)

目 录 摘 要 I Abstract II 1 绪论 1 1.1 课题背景 1 1.2 本课题研究的意义 2 1.3 主要研究内容 3 2 开发环境与相关技术 4 2.1 JSP技术 4 2.1.1 JAVA简介 4 2.1.2 JSP简介 4 2.1.3 SSH2框架介绍 5 2.2 Myeclipse介绍 6 2.3 SQL2008 数据库 7 2.4 Browser/Server(B…

GD32实现串口空闲(IDLE)中断 + DMA机制接收数据

前言 串口功能在单片机开发中,是比较常用的外设,熟练使用串口功能也是驱动开发必备的技能之一。 DMA是一种CPU辅助手段,可以在CPU不参与的情况下,是做一些辅助CPU的事情,如通常的数据搬运。 在没有DMA之前,…

hadoop3.x学习(一)--安装与环境配置

一、hadoop的组成 hadoop1.x:Commons、HDFS(数据存储)、MapReduce(资源调度计算)hadoop2.x:Commons、HDFS(数据存储)、MapReduce(计算)、Yarn(资源调度) 1.1 HDFS 分布式…

【电商项目实战】个人资料(详细篇)

🍁博客主页:👉不会压弯的小飞侠 ✨欢迎关注:👉点赞👍收藏⭐留言✒ ✨系列专栏:👉SpringBoot电商项目实战 ✨学习社区: 👉不会压弯的小飞侠 ✨知足上进&#x…

Linear Model 线性模型

文章目录1、Linear Model 线性模型1.1 问题引入1.2 选择模型1.3 损失 Loss1.4 均方误差 MSE1.5 代码1.6 更换模型1、Linear Model 线性模型 B站视频教程传送门:PyTorch深度学习实践 - 线性模型 1.1 问题引入 假设学生在期末考试中得到y分,如果他们花了…

【正点原子FPGA连载】第二十五章 双路高速AD实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第二十五章 双路…

干货 | 读懂这篇文,玩游戏还会卡顿?

玩游戏的时候最怕的就是卡顿。排位赛的紧急关头,明明马上就能上一段位,却因为卡顿导致给对方送人头。还把对手送上了王者。引起队友骂声一片。作为测试工程师的你,可以忍? 卡顿测试也是专项测试里的一种,更多精彩测试内…

【学习笔记】深度学习入门:基于Python的理论与实现-Python入门与感知机

CONTENTS一、Python入门1.1 NumPy1.2 Matplotlib二、感知机2.1 感知机是什么2.2 简单逻辑电路2.3 感知机的实现2.4 感知机的局限性2.5 多层感知机一、Python入门 1.1 NumPy 在深度学习的实现中,经常出现数组和矩阵的计算。NumPy的数组类(numpy.array&a…

C语言函数调用的过程图解深入剖析

希望是美好的,也许是人间至善,而美好的事物永不消逝。——《肖申克的救赎》 目录 1、什么是函数栈帧? 2、理解函数栈帧能解决什么问题 3、函数栈帧是什么 3.1什么是栈? 3.2认识寄存器和汇编指令 4、函数调用的整个过程 5、…

LBA逻辑区块地址

现在很多硬盘采用同密度盘片,意味着内外磁道上的扇区数量不同,扇区数量增加,容量增加,3D很难定位寻址,出现了新的寻址模式:LBA(Logical Block Addressing)。在LBA地址中,地址不再表示实际硬盘的…

Mysql 并发多版本控制MVCC

什么是MVCC MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 一般情况下我们使用mysql数据库的…

Prometheus 采集vCenter7监控数据

前提要求 安装docker,docker-compose创建vmware_exporter目录 mkdir -p /vmware_exporter 创建基于docker部署vmware_exporter脚本 VSPHERE_HOST: "vCenter 管理地址" VSPHERE_IGNORE_SSL: "True" VSPHERE_USER: "administratorvsphere…

[附源码]计算机毕业设计springboot求职招聘网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

信创平台:查询CPU,内存等命令

信创平台:海光、鲲鹏服务器查询CPU,内存等命令 #1、查看操作系统(统信操作系统) 海光查询操作系统: cat /etc/os-release查看操作系统 cat /etc/os-version查看操作系统版本 鲲鹏查询操作系统:cat /etc/system-release Kylin Linux Adva…

Python图像处理【3】Python图像处理库应用

Python图像处理库应用0. 前言1. 将 RGB 图像转换为灰度图像算法1.1 算法原理3.2 算法实现2. 使用 PIL 库计算图像差异2.1 算法原理2.2 算法实现3. 使用 Scikit-image 转换图像色彩空间3.1 将 RGB 图像转换至 HSV 色彩空间3.2 将 RGB 图像转换至 YUV 色彩空间4. 用 OpenCV 调整图…

html学习笔记

1.在idea里右键创建html文件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body></body> </html>在谷歌浏览器中输入chrome://version可以看…

【学习笔记】深度学习入门:基于Python的理论与实现-误差反向传播法

CONTENTS五、误差反向传播法5.1 计算图5.2 链式法则5.3 反向传播5.4 简单层的实现5.5 激活函数层的实现5.6 Affine/Softmax层的实现5.7 误差反向传播法的实现五、误差反向传播法 5.1 计算图 先引入一个很简单的问题&#xff1a;在超市买了222个100100100元一个的苹果&#xf…