2

I was trying to create a alarm gui using tkinter. I cant update my mainwindow for more than one class object in the list.The problem that i am facing is that after setting the alarm and clicking the save, the alarm object should be seen in the main window [mw()]. This updation is seen only for the first alarm object after that it is not working. The error is only after clicking the save button. But i can assure that the alarm notification [gialarm()] is working on the specific time. Its just my first gui project.

from tkinter import * 
import tkinter.font as tkfont
from datetime import datetime
import winsound

pw=[]
al=[]
i=0
alarml=[]

class alarm:
    onof=1
    def __init__(self,ahour,amin,addon,label):
        self.ahour=ahour
        self.amin=amin
        self.addon=addon
        self.label=label    

def gialarm(i,alarml):
    def notification(i,alarml):
        if alarml[i].addon==1:
            ampm='PM'
        elif alarml[i].addon==0:
            ampm='AM'
        notify=Tk()
        notify.geometry('400x250')
        time=IntVar() 
        ftime=tkfont.Font(size=40)
        nl1=Label(notify,textvariable=time,width=100,font=ftime).pack() 
        lab=IntVar()
        flab=tkfont.Font(size=30)
        nl2=Label(notify,textvariable=lab,width=100,font=flab).pack()
        time.set(f'{alarml[i].ahour}:{alarml[i].amin} {ampm}')
        lab.set(alarml[i].label)
        notify.mainloop()

    while alarml:
        if alarml[i].addon==1:
            h=alarml[i].ahour+12
        elif alarml[i].addon==0:
            h=alarml[i].ahour
        if datetime.now().hour==h and datetime.now().minute==alarml[i].amin:
            winsound.Beep(1000,1000)
            notification(i,alarml)
            break

def mw():

Then i tried creating a update function using 'after' function of tkinter. But it only worked for only first object. Then it dont work for the next saved objects.

    def update_mw():
        global i
        if alarml:
            if alarml[i].addon==1:
                ampm='PM'
            elif alarml[i].addon==0:
                ampm='AM'
            pw.append(PanedWindow(orient=VERTICAL,borderwidth=10,bd=10,bg='green')) 
            onof=IntVar()
            al.append(Checkbutton(alarmgui,text=f'{alarml[i].ahour}:{alarml[i].amin} {ampm}{alarml[i].label}',variable=onof,onvalue=1,offvalue=0))
            pw[i].pack(fill=X)
            pw[i].add(al[i])
            alarmgui.mainloop()
            if onof.get()==1:
                alarml[i].onof=1
            elif onof.get()==0:
                alarml[i].onof=0
            i+=1
        else:
            alarmgui.after(100,update_mw)
            return None
    def save_alarm(add,ahour,amin,addon,label,alarmgui):
        global alarml
        r=alarm(ahour.get(),amin.get(),addon.get(),label.get())
        alarml.append(r)
        add.destroy()
        ahour.set(None)
        amin.set(None)
        addon.set(None)
        label.set(None)

    def set_alarm(alarmgui):
        add=Toplevel()
        add.geometry('300x400')
        lf1=LabelFrame(add,text='Add your alarm').pack(fill='both',expand='yes')    
        l1=Label(add,text='Time:').place(x=10,y=30)

        ahour=IntVar()
        sb1=Spinbox(add,from_=1,to=12,textvariable=ahour,width=5).place(x=140,y=30)
        l2=Label(add,text=':').place(x=190,y=30)
        amin=IntVar()
        sb1=Spinbox(add,from_=0,to=59,textvariable=amin,width=5).place(x=200,y=30)

        addon=IntVar()
        r1=Radiobutton(add,text='AM',variable=addon,value=0).place(x=140,y=60)
        r2=Radiobutton(add,text='PM',variable=addon,value=1).place(x=190,y=60)

        label=StringVar()
        e1=Entry(add,textvariable=label).place(x=130,y=100,width=150)
        l3=Label(add,text='Alarm label:').place(x=10,y=100)
        b2=Button(add,text='Save Alarm',width=30,height=2,command=lambda: save_alarm(add,ahour,amin,addon,label,alarmgui)).pack(side='bottom')
        add.mainloop()

    alarmgui=Tk()
    alarmgui.geometry('500x500')
    b1=Button(alarmgui,text='ADD ALARM',width=30,height=2,command=lambda: set_alarm(alarmgui)).place(x=150,y=450)
    alarmgui.after(1,update_mw)
    alarmgui.mainloop()

mw()

for i in range(len(alarml)):
        if alarml[i].onof:
            gialarm(i,alarml)
GIJoe 143
  • 29
  • 3
  • 1
    Read [Why are multiple instances of Tk discouraged?](https://stackoverflow.com/a/48045508/7414759) and [When to use the Toplevel Widget](http://effbot.org/tkinterbook/toplevel.htm) and [Tkinter understanding mainloop](https://stackoverflow.com/a/29158947/7414759) and [tkinter: how to use after method](https://stackoverflow.com/a/25753719/7414759) – stovfl Jun 11 '20 at 09:30
  • Does these links concludes that to work in just one window??@stovfl – GIJoe 143 Jun 12 '20 at 07:51
  • ***to work in just one window?***: No, **ONE** `root` which is **ONE** `tk..Tk()`. You have to use the `Toplevel` widget to open multiple windows, see the second link. – stovfl Jun 12 '20 at 07:55
  • Yes..I have used **Toplevel** to open the window to set the timing of the alarm.But, the problem that i am facing is that **after setting the alarm and clicking the save, the alarm object should be seen in the main window [mw()]**. This updation is seen only for the first alarm object after that it is not working. The error is only after clicking the save button..!!!But i can assure that the alarm notification is working on the specific time..@stovfl – GIJoe 143 Jun 13 '20 at 06:12
  • ***The error is only after clicking the save button***: [Edit] your question and show the Traceback, edit also your example to show your changes. You are using also this antipattern: [AttributeError: NoneType object has no attribute](https://stackoverflow.com/a/1101765/7414759) – stovfl Jun 13 '20 at 07:29
  • Still using **multiple `TK()`** and **`.mainloop()`**! Nothing improved at all! Still no Traceback shown! – stovfl Jun 14 '20 at 09:36

0 Answers0