某一个“天” 发表于 2024-7-31 18:22:22

第三版电子钟震撼来袭!炫酷变色效果,多线程灵动使用

本帖最后由 某一个“天” 于 2024-8-16 09:50 编辑

设计思路:
刚开始只是写着玩玩,后来发现这时钟挺有意思,没多想就扩展了许多功能。顺便学了一下多线程,
其实只要打好基础,这个真的很简单~(甲鱼哥的教程是真的用心,节奏快,干货多{:10_256:})
未来前景:
加上时钟表盘,优化多线程,完善计时器
程序解释:
首先介绍一下新加的渐变色效果:
def make_it_more_beautiful():
    # 矩形属性
    rect = canvas.create_rectangle(10, 10, 580, 350, outline='red', width=40)
    # RGB颜色循环
    r, g, b = 255, 0, 0# 初始颜色为红色

    while True:
      # 每0.1秒更新一次颜色
      time.sleep(0.1)
      # RGB颜色渐变
      r = (r - 1) % 256
      g = (g + 2) % 256
      b = (b + 1) % 256

      # 更新矩形颜色
      canvas.itemconfig(rect, outline=f'#{r:02x}{g:02x}{b:02x}')
就是画一个初始边缘颜色为红的矩形,每 0.1 秒变一次色,但并不是总丝滑


运行结束会有 RuntimeError,不用理?
因为tkinter其实不太支持多线程,而after有时出错!

最后是完整代码,想试一下的记得准备音乐
import time
import threading
import tkinter as tk
from tkinter.messagebox import *
from tkinter.ttk import Combobox, Progressbar
import pygame


def make_it_more_beautiful():
    # 矩形属性
    rect = canvas.create_rectangle(10, 10, 580, 350, outline='red', width=40)
    # RGB颜色循环
    r, g, b = 255, 0, 0# 初始颜色为红色

    while True:
      # 每0.1秒更新一次颜色
      time.sleep(0.1)
      # RGB颜色渐变
      r = (r - 1) % 256
      g = (g + 2) % 256
      b = (b + 1) % 256

      # 更新矩形颜色
      canvas.itemconfig(rect, outline=f'#{r:02x}{g:02x}{b:02x}')


def clock_start_or_pause():
    global clock_is_running, start_or_pause_button, reset
    clock_is_running = not clock_is_running
    reset = False
    text_list = ["继续", "暂停"]
    start_or_pause_button.config(text=text_list)

    clock_run()


def clock_run():
    def job2():
      global clock_is_running, last_h, last_m, last_s, last_ms
      while clock_is_running:
            set_h = str(last_h).zfill(2)
            set_m = str(last_m).zfill(2)
            set_s = str(last_s).zfill(2)
            set_ms = str(last_ms).zfill(3)
            var_last_time.set(set_h + ":" + set_m + ":" + set_s + "." + set_ms)

            time.sleep(0.001)
            last_ms += 1
            if last_ms == 1000:
                last_ms = 0
                last_s += 1
                if last_s == 60:
                  last_s = 0
                  last_m += 1
                  if last_m == 1000:
                        last_m = 0
                        last_h += 1
      if reset:
            var_last_time.set("00:00:00.000")

    clock_job = threading.Thread(target=job2)
    clock_job.start()


def remember_last_time():
    global times
    times += 1
    times_box.insert(times, "计次" + str(times) + "-" + var_last_time.get())


def reset_clock():
    global clock_is_running, last_h, last_m, last_s, last_ms, times, var_last_time, times_box, reset
    times_box.delete(0, tk.END)
    reset = True
    clock_is_running = False
    last_h, last_m, last_s, last_ms, times = 0, 0, 0, 0, 0
    start_or_pause_button.config(text="开始")
    var_last_time.set("00:00:00.000")


def count(h, m, s):
    total_seconds = h * 3600 + m * 60 + s

    def job():
      count_pro.start(total_seconds)# total_seconds*1000/1000
      time.sleep(total_seconds)

      count_pro.stop()
      showinfo("嘿", "倒计时结束了")
      top3.destroy()

    count_job = threading.Thread(target=job)
    count_job.start()


def now_time():
    global var_now, var_nowday
    var_now.set(time.strftime('%H:%M:%S'))
    # 考虑到程序持续到第二天
    if var_now == "00:00:00":
      var_nowday.set(time.strftime("%Y-%m-%d %a."))
    win.after(1000, now_time)


def ok_time():
    if entry1.get() == "":
      showinfo("", "输入为空")
    else:
      top1.iconify()
      if var_now.get() == entry1.get():
            pygame.mixer.music.load(combobox1.get())
            pygame.mixer.music.play(-1)
            showinfo(f"It's time to...", f"到点了~{var_now.get()}\n{entry2.get()}")
            pygame.mixer.music.stop()
            top1.destroy()

      top1.after(1000, ok_time)


def Top1():
    global top1, entry1, entry2, combobox1
    try:
      top1.destroy()
    except:
      pass

    top1 = tk.Toplevel(win)
    top1.geometry("250x250")
    top1.title("闹钟")

    label1_1 = tk.Label(top1, text="当前时间:", font=("黑体", 15), height=2)
    label1_1.grid(row=0, column=0)
    label1_2 = tk.Label(top1, textvariable=var_now, font=("黑体", 15), height=2)
    label1_2.grid(row=0, column=1)

    label1_3 = tk.Label(top1, text="闹钟时间:", font=("黑体", 15), height=2)
    label1_3.grid(row=1, column=0)
    # 设定 justify 属性,其定义是输入控件中文本的对齐方式。
    # 可以设置的数值为:LEFT,CENTER, RIGHT。默认数值是LEFT。
    entry1 = tk.Entry(top1, font=("黑体", 15), width=13, bg="#FFEBCD", justify='center')
    entry1.insert(0, var_now.get())
    entry1.grid(row=1, column=1)

    label4 = tk.Label(top1, text="提示词:", font=("黑体", 15), height=2)
    label4.grid(row=2, column=0)
    entry2 = tk.Entry(top1, textvariable=var_tip_label, font=("微软雅黑 Light", 15),
                      width=13, bg="#FFEBCD")
    entry2.grid(row=2, column=1)

    label5 = tk.Label(top1, text="闹钟音乐:", font=("黑体", 15), height=2)
    label5.grid(row=3, column=0)
    combobox1 = Combobox(top1, values=music, width=12, font=("楷体", 13))
    combobox1.current(0)# current(index):设置默认选中索引为index的选项
    combobox1.grid(row=3, column=1)

    ok_button_1 = tk.Button(top1, text="确定", font=25, width=10, bg="#00f5ff", command=ok_time)
    ok_button_1.grid(row=4, column=0, columnspan=2, pady=30)


def Top2():
    global top2, clock_is_running, start_or_pause_button, times_box
    try:
      top2.destroy()
    except:
      pass

    top2 = tk.Toplevel(win)
    top2.geometry("335x425")
    top2.title("秒表")

    last_time_label = tk.Label(top2, textvariable=var_last_time, font=("微软雅黑 Light", 40))
    last_time_label.grid(row=0, column=0, columnspan=3)

    start_or_pause_button = tk.Button(top2, text="开始", font=("黑体", 15), bg="green", command=clock_start_or_pause)
    start_or_pause_button.grid(row=1, column=0)
    remember_button = tk.Button(top2, text="计次", font=("黑体", 15), fg="purple", command=remember_last_time)
    remember_button.grid(row=1, column=1)
    reset_button = tk.Button(top2, text="重置", font=("黑体", 15), bg="orange", command=reset_clock)
    reset_button.grid(row=1, column=2)

    times_box = tk.Listbox(top2, font=("微软雅黑", 18), fg="blue", width=20, height=10)
    times_box.grid(row=3, column=0, columnspan=3)


def Top3():
    global top3, count_pro
    try:
      top3.destroy()
    except:
      pass

    top3 = tk.Toplevel(win)
    top3.geometry("260x380")

    label3_1 = tk.Label(top3, text="定时器时长(时:分:秒)", font=("黑体", 15), fg="orange", height=2)
    label3_1.grid(row=0, column=0, columnspan=3)

    sc1 = tk.Scale(top3, length=200, label=":", from_=0, to=23, tickinterval=2, bg="orange")
    sc1.grid(row=1, column=0)

    sc2 = tk.Scale(top3, length=200, label=":", from_=0, to=59, tickinterval=10, bg="orange")
    sc2.grid(row=1, column=1)

    sc3 = tk.Scale(top3, length=200, from_=0, to=59, tickinterval=10, bg="orange")
    sc3.grid(row=1, column=2)

    count_pro = Progressbar(top3, value=0, length=200, maximum=1000)
    count_pro.grid(row=2, column=0, columnspan=3, pady=15)

    ok_button_3 = tk.Button(top3, text="确定", font=25, width=10, bg="#00f5ff",
                            command=lambda: count(sc1.get(), sc2.get(), sc3.get()))
    ok_button_3.grid(row=3, column=0, columnspan=3, pady=30)


music = ["清脆.mp3", "大爆炸.wav"]

pygame.init()
pygame.mixer.music.set_volume(0.5)

win = tk.Tk()
var_nowday = tk.StringVar()
var_now = tk.StringVar()
var_tip_label = tk.StringVar()
var_tip_label.set("闹钟")
clock_is_running = False
reset = False
last_h = last_m = last_s = last_ms = 0
var_last_time = tk.StringVar()
var_last_time.set("00:00:00.000")
times = 0
win.geometry("587x357")
# 创建Canvas
canvas = tk.Canvas(win, width=600, height=370, bg="white")
canvas.pack()
beautiful_job = threading.Thread(target=make_it_more_beautiful)
beautiful_job.start()

var_nowday.set(time.strftime("%Y-%m-%d %a."))
var_now.set(time.strftime("%H:%M:%S"))

day_label = tk.Label(canvas, textvariable=var_nowday, font=("微软雅黑", 30))
day_label.grid(row=0, column=0, columnspan=3)
time_label = tk.Label(canvas, textvariable=var_now, font=("微软雅黑", 60), fg="red")
time_label.grid(row=1, column=0, columnspan=3)
button1 = tk.Button(canvas, text="闹钟", font=("微软雅黑", 15), width=10, height=3, command=Top1)
button1.grid(row=2, column=0, padx=33, pady=45)
button2 = tk.Button(canvas, text="秒表", font=("微软雅黑", 15), width=10, height=3, command=Top2)
button2.grid(row=2, column=1, padx=33, pady=45)
button3 = tk.Button(canvas, text="倒计时", font=("微软雅黑", 15), width=10, height=3, command=Top3)
button3.grid(row=2, column=2, padx=33, pady=45)

now_time()

win.mainloop()悄悄求个评分~
@不二如是 @sfqxx @zhangjinxuan @python爱好者. @KeyError @isdkz @小甲鱼的三师弟 @ba21 @Twilight6 @洛十三 @三体人的智子

不二如是 发表于 2024-7-31 18:39:25

时钟大全{:10_256:}

sunshine_8205 发表于 2024-7-31 19:01:09

不二如是 发表于 2024-7-31 18:39
时钟大全

{:5_106:}

ba21 发表于 2024-7-31 19:07:10

期待有更好的版本。

wp231957 发表于 2024-7-31 19:21:48

才3鱼币,太小气

某一个“天” 发表于 2024-7-31 19:56:06

ba21 发表于 2024-7-31 19:07
期待有更好的版本。

有什么完善建议吗

歌者文明清理员 发表于 2024-8-1 09:52:07

win7让我回忆起了几年前{:10_266:}

简柠啦 发表于 2024-8-1 12:18:39

{:10_266:}{:10_266:}

某一个“天” 发表于 2024-8-1 13:19:30

歌者文明清理员 发表于 2024-8-1 09:52
win7让我回忆起了几年前

嘿嘿,马上就用win11继续开发了{:10_256:}

芜湖666 发表于 2024-8-1 17:31:51

sss

小肥狼haoran 发表于 2024-8-2 08:57:58

有点东西,来看看

KeyError 发表于 2024-8-4 16:57:17

把字体改成Con就完美了!

某一个“天” 发表于 2024-8-4 17:43:22

KeyError 发表于 2024-8-4 16:57
把字体改成Con就完美了!

什么是Con

零食羊 发表于 2024-8-4 20:13:00

{:10_256:}{:10_257:}

三体人的智子 发表于 2024-8-9 10:06:18

有点迟到,哈哈

祝你早日精华帖!{:10_275:}

格子penbeat 发表于 2024-8-15 15:52:11

哎哟 不错哦 马上试试

林木荟蔚 发表于 2024-8-15 15:52:17

效果很棒,赶紧用起来

zhae89 发表于 2024-8-15 15:52:47

狂拽酷炫那个什么炸天

王一学python 发表于 2024-8-15 15:53:17

这个效果我喜欢

泼墨染笛香 发表于 2024-8-15 15:53:48

加油
页: [1] 2 3 4
查看完整版本: 第三版电子钟震撼来袭!炫酷变色效果,多线程灵动使用