ChrisBoss
ChrisBoss

Reputation: 25

Display console on screen

so I have a basic alarm python GUI, nothing fancy is still in need of a lot of work. So currently my code works as follow: The user clicks "create new alarm" and it opens a window with 3 option menu widgets and selected the time he wants the alarm to go off, then once the set alarm is clicked a loop is run that counts down at one second every time the loop is repeated and the time is printed in the console than when the time they set is equal to the current time the alarm goes off.

Now my problem is that I want that countdown that is in the console to be displayed on the GUI. I tried to simply make a label and use .get to fetch the current value and display them but once the loop starts it won't do any other code. If I have any other suggestions I am all ears. All i want is a countdown that shows how much time till the alarm goes off, my current idea in my trial and error plan is to display the console.

Here is my code:

# Import Required Library
from tkinter import *
import datetime
import time
import winsound
from threading import *
from tkinter import messagebox

def submit():

    def alarm(Curent):
        # Infinite Loop
        while True:
            # Set Alarm
            set_alarm_time = f"{hour.get()}:{minute.get()}:{second.get()}"

            # Wait for one seconds
            time.sleep(1)

            # Get current time
            current_time = datetime.datetime.now().strftime("%H:%M:%S")
            print(current_time,set_alarm_time)

            Curent = current_time
            set = set_alarm_time


            # Check whether set alarm is equal to current time or not
            if current_time == set_alarm_time:
                print("Time to Wake up")
                # Playing sound
                winsound.PlaySound("sound.wav",winsound.SND_ASYNC)
                messagebox.showinfo(title="ALARM", message="Alarm is going off, its time to wake up!")
                break


    root = Tk()
    root.geometry("400x300")
    root.config(bg="#447c84")
    root.title('MathAlarm')

    # Add Labels, Frame, Button, Optionmenus
    Label(root,text="Alarm Clock",font=("Helvetica 20 bold"),fg="Black").pack(pady=10)
    Label(root,text="Set Time",font=("Helvetica 15 bold")).pack()

    frame = Frame(root)
    frame.pack()

    hour = StringVar(root)
    hours = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23', '24'
            )
    hour.set(hours[0])

    hrs = OptionMenu(frame, hour, *hours)
    hrs.pack(side=LEFT)

    minute = StringVar(root)
    minutes = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23',
            '24', '25', '26', '27', '28', '29', '30', '31',
            '32', '33', '34', '35', '36', '37', '38', '39',
            '40', '41', '42', '43', '44', '45', '46', '47',
            '48', '49', '50', '51', '52', '53', '54', '55',
            '56', '57', '58', '59', '60')
    minute.set(minutes[0])

    mins = OptionMenu(frame, minute, *minutes)
    mins.pack(side=LEFT)

    second = StringVar(root)
    seconds = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23',
            '24', '25', '26', '27', '28', '29', '30', '31',
            '32', '33', '34', '35', '36', '37', '38', '39',
            '40', '41', '42', '43', '44', '45', '46', '47',
            '48', '49', '50', '51', '52', '53', '54', '55',
            '56', '57', '58', '59', '60')
    second.set(seconds[0])

    secs = OptionMenu(frame, second, *seconds)
    secs.pack(side=LEFT)

    Button(root,text="Set Alarm",font=("Helvetica 15"),command=alarm).pack(pady=20)
    Button(root,text="Exit",font=("Helvetica 15"), command=lambda:root.destroy()).pack(pady=20)

root = Tk()
root.title('MathAlarm')
root.geometry('347x400')
root.config(bg="#447c84")

welcomelabel = Label(root, text="Welcome to Math Alarm", font=("Times", "24", "bold"))
welcomelabel.pack()

ext = Button(root, text="Exit", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=lambda:root.destroy())
reg = Button(root, text="Create new Alarm", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=submit)
ext.pack()
reg.pack()

# Execute Tkinter
root.mainloop()`

Upvotes: 1

Views: 419

Answers (1)

Zain Ul Abidin
Zain Ul Abidin

Reputation: 2690

Well I tried a different approach which does not uses the custom threading at all but uses tkinter's own main loop, it has it's own drawbacks and advantages too. I made following changes in your code to make it work

  1. Global variables for hours, mins and seconds
  2. Global variable for the output label
  3. Separated your alarm function from submit function
  4. Removed alarm function from button command

There is an option in the tkinter to run a function withing the main loop of tkinter periodically that way you won't be blocking any events processing of tkinter or any other process as tkinter itself take care of that check documentation of root.after(time, function) for more details.

# Import Required Library
from tkinter import *
import datetime
import time
import winsound
from threading import *
from tkinter import messagebox

mainLabel = None
(h, m, s) = (None, None, None)
root = None

def alarm():
    global mainLabel
    
    set_alarm_time = f"{h}:{m}:{s}"
    current_time = datetime.datetime.now().strftime('%H:%M:%S')

    mainLabel['text'] = current_time #update current time in label, you can show whatever you want
    print(current_time, set_alarm_time)

    # Check whether set alarm is equal to current time or not
    if current_time == set_alarm_time:
        print("Time to Wake up")
        # Playing sound
        winsound.PlaySound("sound.wav", winsound.SND_ASYNC)
        messagebox.showinfo(title="ALARM", message="Alarm is going off, its time to wake up!")
        #no more need to schedule the function 
    else:
        #alarm time is not reached let's schedule the function again for one second
        root.after(1000, alarm)

def submit():
    global mainLabel
    
    def start():
        global h, m, s, hours, mins, secs
        
        print('scheduling alarm')
        h = hour.get()
        m = minute.get()
        s = second.get()
        (hours, mins, secs) = (int(h), int(m), int(s))
        root.after(1000, alarm)
        
    root = Tk()
    root.geometry("400x300")
    root.config(bg="#447c84")
    root.title('MathAlarm')

    # Add Labels, Frame, Button, Optionmenus
    Label(root,text="Alarm Clock",font=("Helvetica 20 bold"),fg="Black").pack(pady=10)
    mainLabel = Label(root,text="Set Time",font=("Helvetica 15 bold"))
    mainLabel.pack()
    
    frame = Frame(root)
    frame.pack()

    hour = StringVar(root)
    hours = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23', '24'
            )
    hour.set(hours[0])

    hrs = OptionMenu(frame, hour, *hours)
    hrs.pack(side=LEFT)

    minute = StringVar(root)
    minutes = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23',
            '24', '25', '26', '27', '28', '29', '30', '31',
            '32', '33', '34', '35', '36', '37', '38', '39',
            '40', '41', '42', '43', '44', '45', '46', '47',
            '48', '49', '50', '51', '52', '53', '54', '55',
            '56', '57', '58', '59', '60')
    minute.set(minutes[0])

    mins = OptionMenu(frame, minute, *minutes)
    mins.pack(side=LEFT)

    second = StringVar(root)
    seconds = ('00', '01', '02', '03', '04', '05', '06', '07',
            '08', '09', '10', '11', '12', '13', '14', '15',
            '16', '17', '18', '19', '20', '21', '22', '23',
            '24', '25', '26', '27', '28', '29', '30', '31',
            '32', '33', '34', '35', '36', '37', '38', '39',
            '40', '41', '42', '43', '44', '45', '46', '47',
            '48', '49', '50', '51', '52', '53', '54', '55',
            '56', '57', '58', '59', '60')
    second.set(seconds[0])

    secs = OptionMenu(frame, second, *seconds)
    secs.pack(side=LEFT)

    Button(root,text="Set Alarm",font=("Helvetica 15"), command=start).pack(pady=20)
    Button(root,text="Exit",font=("Helvetica 15"), command=lambda:root.destroy()).pack(pady=20)

root = Tk()
root.title('MathAlarm')
root.geometry('347x400')
root.config(bg="#447c84")

welcomelabel = Label(root, text="Welcome to Math Alarm", font=("Times", "24", "bold"))
welcomelabel.pack()

ext = Button(root, text="Exit", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=lambda:root.destroy())
reg = Button(root, text="Create new Alarm", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=submit)
ext.pack()
reg.pack()

root.mainloop()

The output is following

NOTE: The answer is only for showing, how to update tkinter's label value in GUI which was the actual problem.

enter image description here

Upvotes: 1

Related Questions