【问题标题】:Is function inheritance possible like class inheritance in python? [closed]函数继承可以像python中的类继承一样吗? [关闭]
【发布时间】:2019-11-15 13:09:29
【问题描述】:
from tkinter import *
from tkinter import messagebox
import pygame
import time
pygame.init()
def alarm_time():
    hrs = int(hrs_opt_ctrl.get())
    min = int(min_opt_ctrl.get())
    tme = tme_ctrl.get()
    if hrs == int(time.strftime('%I')) and min == int(time.strftime('%M')) and tme == time.strftime('%p'):
        # Time is up. Play the sound
        alarm_ringtone = pygame.mixer.music.load('alarm_noise.mp3')
        pygame.mixer.music.play()
        # Don't call after again
    else:
        # Not time, sleep for 1 second
        window.after(1000, alarm_time)

def snooze_time():
    snoz_min=(2,5,10,20,30,35,40,45,50,55,59)
    snooze=True
    while snooze:
        try:
            min = min + int(snoz_min[minute])
            window.after((min)*1000,alarm_time)
        except:
            messagebox.showerror("Error 404", "Cannot Snooze for given Time")
        if minute<=len(snoz_min):
            minute+=1
        elif minute!=len(snoz_min):
            minute=0
        else:
            pass
    snooze=False

window=Tk()
window.title('Alarm')
window.config(background='black')
logo=PhotoImage(file='alarm.gif')
lab_1=Label(window,text='Alarm',bg='black',fg='white',font=('Times',25,'bold')).grid(column=100,row=0)
lab_2=Label(window,bg='black',image=logo).grid(column=300,row=0)
lab_3=Label(window,text='Hours',bg='black',fg='white',font=('Comic',10,'bold')).grid(column=50,row=130)
lab_4=Label(window,text='Minutes',bg='black',fg='white',font=('Comic',10,'bold')).grid(column=85,row=130)
opt_hrs=[]
opt_min=[]
opt_tme=('AM','PM')
minute=0
for i in range(1,13):
    opt_hrs.append(i)
for j in range(0,60):
    opt_min.append(j)
hrs_opt_ctrl=StringVar()
min_opt_ctrl=StringVar()
tme_ctrl=StringVar()
tme_ctrl.set(opt_tme[0])
hrs_lab=OptionMenu(window,hrs_opt_ctrl,*opt_hrs).grid(column=60,row=130,columnspan=15)
min_lab=OptionMenu(window,min_opt_ctrl,*opt_min).grid(column=86,row=130,columnspan=15)
tme_lab=OptionMenu(window,tme_ctrl,*opt_tme).grid(column=150,row=130)
but_1=Button(window,text='Set Alarm',font=('Comic',10,'bold'),command=alarm_time).grid(column=100,row=240)
but_2=Button(window,text='Snooze',font=('Comic',10,'bold'),command=snooze_time).grid(column=100,row=250)
window.mainloop()

以下代码在运行时不显示任何错误但不播放警报。 警报文件的扩展名为 .mp3,与项目位于同一文件夹中。 我可能认为时间模块代码有问题 或“设置警报”按钮未接受任何输入。列和行的位置不准确

【问题讨论】:

  • 看起来您需要在设置闹钟时按下按钮。你这样做吗? How to create a timer using tkinter?
  • 是的,我正在按下按钮,但没有任何响应
  • 你做了什么来调试这个?您是否验证了hrsmintme 是您认为的那样?另外,你为什么希望它播放?看起来您已将其设计为仅在您在正确的时间单击按钮时才播放。
  • 哦不知道。有没有办法纠正这个问题?
  • @4shwin_26 抱歉我删除了\ 。应该阅读:在if ... 条件之前添加print('{}=={} and {}=={} and {}=={}'.format(hrs, time.strftime('%I'), min, time.strftime('%M'), tme, time.strftime('%p')))

标签: python python-3.x tkinter pygame


【解决方案1】:

如 cmets 中所述,您已将其设置为仅当用户在设置闹钟时单击按钮时才播放闹钟。相反,您应该每秒检查一次时间,并在给定时间播放警报:

def alarm_time():
    hrs = int(hrs_opt_ctrl.get())
    min = int(min_opt_ctrl.get())
    tme = tme_ctrl.get()
    if hrs == int(time.strftime('%I')) and min == int(time.strftime('%M')) and tme == time.strftime('%p'):
        # Time is up. Play the sound
        alarm_ringtone = pygame.mixer.music.load('alarm_noise.mp3')
        pygame.mixer.music.play()
        # Don't call after again
    else:
        # Not time, sleep for 1 second
        window.after(1000, alarm_time)

注意,我将所有内容都转换为 int,因为 time.strftime('%I')time.strftime('%M') 返回 0-pre-padded 字符串,而您的选项框没有 0-pre-padded 值,所以 "1" != "01" 等。


更新了多个警报和贪睡的答案。我只是把它放在一起,所以还有很大的改进空间:

from tkinter import *
import pygame
import time

pygame.mixer.init()

window = Tk()
window.geometry('300x200')
window.title('Alarm')

#logo = PhotoImage(file='alarm.gif')

lab_1 = Label(window, text='Alarm Clock', font=('Times',20,'bold')).grid(column=200, row=0)
#lab_2=Label(window,image=logo).grid(column=300,row=0,columnspan=3)
lab_3 = Label(window, text='Hours', font=('Comic',10,'bold')).grid(column=50,row=10, columnspan=3)
lab_4 = Label(window, text='Minutes', font=('Comic',10,'bold')).grid(column=90,row=10, columnspan=3)

# Alarm class
class Alarm:
    alarm_id = 1
    def __init__(self, hours, minutes, ampm, sound_file):
        self.sound_file = sound_file
        # Convert hours, minutes, ampm to a timestamp
        # Save time as a timestamp
        t = time.localtime()
        t = time.strptime(f"{t.tm_year}-{t.tm_mon}-{t.tm_mday} {hours} {minutes} {ampm}", "%Y-%m-%d %I %M %p")
        self.alarm_time = time.mktime(t)
        # Number of seconds to snooze
        self.snooze_time = None
        self.completed = False   # Set to True after alarm has gone off
        self.id = Alarm.alarm_id
        Alarm.alarm_id += 1

    # Every time this is called, it checks the time to see if the alarm should go off
    def check_time(self, cur_time):
        # Use alarm time or snooze time?
        on_time = self.snooze_time if self.snooze_time else self.alarm_time
        # Since might not be called when seconds is 0, check if it is with one minute of alarm time
        time_diff = cur_time - on_time
        if not self.completed and time_diff >= 0 and time_diff < 60:
            self.completed = True
            alarm_ringtone = pygame.mixer.music.load(self.sound_file)
            pygame.mixer.music.play()
        # Reset after 30 minutes - add 24 hours (daily timer)
        elif self.completed and time_diff > 1800 and time_diff < 1860:
            self.completed = False
            self.snooze_time = None
            self.alarm_time += 24 * 60 * 60

    def snooze(self, minutes):
        if self.completed and pygame.mixer.music.get_busy():
            self.snooze_time = time.time() + (minutes * 60)
            self.completed = False
            pygame.mixer.music.stop()

    # Convert to string for printing
    def __str__(self):
        id_str = f"[{self.id}]: "
        if self.completed:
            return id_str + ("Alarm in progress" if pygame.mixer.music.get_busy() else "Alarm completed")
        elif self.snooze_time:
            time_left = int(self.snooze_time - time.time())
            minutes = time_left // 60
            seconds = time_left % 60
            if minutes:
                return id_str + f"Snoozing for {minutes} minutes and {seconds} seconds"
            else:
                return id_str + f"Snoozing for {seconds} seconds"
        else:
            return id_str + f"Alarm set for {time.ctime(self.alarm_time)}"

# This list holds all alarms
all_alarms = []

# Tell all alarms to check the time
def check_alarms():
    now = time.time()
    for alarm in all_alarms:
        print(f"Checking: {alarm}");
        alarm.check_time(now)
    # Call again after 1 second
    window.after(1000, check_alarms)

# Creates a single object of the Alarm class
# Uses values from the option controls
def create_alarm():
    hours = int(hrs_opt_ctrl.get())
    minutes = int(min_opt_ctrl.get())
    ampm = tme_ctrl.get()
    alarm = Alarm(hours, minutes, ampm, "alarm.mp3")
    all_alarms.append(alarm)
    print(f"Adding: {alarm}");

# Snoozes all active alarms for 2 minutes
def snooze_current():
    for alarm in all_alarms:
        alarm.snooze(2)

but = Button(window, text='Set Alarm', font=('Comic',10,'bold'), command=create_alarm).grid(column=100,row=15)
snooze = Button(window, text='Snooze', font=('Comic',10,'bold'), command=snooze_current).grid(column=100,row=16)
opt_hrs = []
opt_min = []
opt_tme = ('AM','PM')
for i in range(1,13):
    opt_hrs.append(i)
for j in range(0,60):
    opt_min.append(j)

hrs_opt_ctrl = StringVar()
min_opt_ctrl = StringVar()
tme_ctrl = StringVar()
hrs_lab = OptionMenu(window, hrs_opt_ctrl, *opt_hrs).grid(column=70,row=10,columnspan=3)
min_lab = OptionMenu(window, min_opt_ctrl, *opt_min).grid(column=100,row=10,columnspan=3)
tme_lab = OptionMenu(window, tme_ctrl, *opt_tme).grid(column=120,row=10,columnspan=3)

# Fill with default values of current time
hrs_opt_ctrl.set(str(int(time.strftime('%I'))))
min_opt_ctrl.set(str(int(time.strftime('%M'))))
tme_ctrl.set(time.strftime('%p'))

check_alarms()
window.mainloop()
pygame.mixer.music.stop()

【讨论】:

  • 啊啊啊啊啊啊啊啊!!!谢谢老哥!!
  • 只是问,有没有办法进一步优化代码?喜欢添加多个闹钟打盹?
  • @4shwin_26 对于这样一个简单的程序,优化它可能没有太多工作要做。一件事是根据警报前的时间来修改程序休眠的时间。例如:如果闹钟离闹钟还有 1 小时,则睡 59 分钟,但如果闹钟是 5 分钟,则睡 4 分钟,等等。请注意,还有另一个网站 Code Review,您可以在其中发布工作 编写代码并让其他人对其进行审核并提供建议。此外,添加多个闹钟打盹 不是优化。它们是您可以添加的功能。
  • 你能告诉我如何打盹和添加多个闹钟吗?
  • @4shwin_26 贪睡很简单:添加一个贪睡按钮,然后在用户点击贪睡时将闹钟时间增加几分钟,(不要忘记再次调用after重新启动计时器)。多个警报将更加复杂。你熟悉类吗?
猜你喜欢
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多