0

I'm trying to write a shutdown timer in Python as a newbie programmer. The purpose of the program is to accept a time in a GUI entry box and when the user clicks the shutdown/restart button to start a timer, showing the remaining time in the same window.

Currently, I've got the program to basically function but I don't know how to make the timer update properly (except in a crude print() timer). I see that there are some answers on other programming languages but I'm not yet fluent in those. Also, as I've said, I'm a new programmer so if you see anything else that I could do better I would welcome constructive criticism.

# This program accepts a time value for shutdown/restart
# counts down, shutting down the system at the end of the timer.

import tkinter
import time
import os

class ShutdownTimerGUI:
    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()

        # Create three frames to group widgets.
        self.top_frame = tkinter.Frame()
        self.mid_frame = tkinter.Frame()
        self.bottom_frame = tkinter.Frame()

        # Create the widgets for the top frame.

        self.prompt_label = tkinter.Label(self.top_frame, \
                                      text='Enter the number of minutes until shutdown:')
        self.time_entry = tkinter.Entry(self.top_frame, \
                                    width=3)

        # Pack the top frame's widgets.
        self.prompt_label.pack(side='left')
        self.time_entry.pack(side='left')

        # Create the widgets for the middle frame.
        self.descr_label = tkinter.Label(self.mid_frame, \
                                     text='Time until shutdown:')

        # Associate a StringVar object with the output label. Use the object's
        # set method to store a string of blank characters.
        self.value = tkinter.StringVar()

        # Create a label and associate it with the StringVar object. Any
        # value stored in the StringVar object will automatically be displayed
        # in the label.
        self.time_label = tkinter.Label(self.mid_frame, \
                                    textvariable=self.value)

        # Pack the middle frame's widgets.
        self.descr_label.pack(side='left')
        self.time_label.pack(side='left')

        # Create the button widgets for the bottom frame.
        self.shutdown_button = tkinter.Button(self.bottom_frame, \
                                          text='Shutdown', \
                                          command=self.shutdown)
        self.restart_button = tkinter.Button(self.bottom_frame, \
                                          text='Restart', \
                                          command=self.restart)
        self.shutdown_button.pack()
        self.restart_button.pack()

        # Pack the buttons.
        self.top_frame.pack()
        self.mid_frame.pack()
        self.bottom_frame.pack()

        #Enter the tkinter main loop.

        tkinter.mainloop()

    # The shutdown method is a callback function for the Shutdown Button.

    def shutdown(self):
        # Get the value entered by the user into the time_entry widget.
        minutes = float(self.time_entry.get())
        seconds = minutes * 60
        count = 0
        self.time_left()
        os.system('shutdown /s')

    # The restart method is a callback function for the Restart Button.

    def restart(self):
        # Get the value entered by the user into the time_entry widget.
        minutes = float(self.time_entry.get())
        seconds = minutes * 60
        count = 0
        self.time_left()
        os.system('shutdown /r')

    def time_left(self):
        minutes = float(self.time_entry.get())
        seconds = minutes * 60
        count = 0
        while count < seconds:
            time.sleep(1)
            count += 1
            time_left = seconds - count
            print(time_left)
            self.value.set(time_left)


Shutdown_Timer = ShutdownTimerGUI()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • What is your specific question? Stack Overflow is not a code review site (there is a Stack Exchange site for that already.) What problem, exactly, are you trying to solve? –  Jan 12 '18 at 18:45
  • @jdv I need to know how to make my timer update once a second in the main window. I posted my entire code because I wasn't sure where my logical error was. I think my error was either on line 36 declaring the StringVar() or in the time_left() at the end of the code, but am not sure. – user717955 Jan 12 '18 at 19:51
  • Much discussed already. For example, in Tkinter: https://stackoverflow.com/q/35899430/1531971 or even https://github.com/Swipe650/pytimer There are others. The idea is that you have another thread updating your UI, but this will be somewhat specific to the GUI API. –  Jan 12 '18 at 20:17
  • @jdv: you don't need threads to do a simple timer in tkinter. – Bryan Oakley Jan 13 '18 at 14:13
  • @BryanOakley the assumption is that Tkinter has the notion of a "GUI Thread" and some functionality to have something done off that thread, which is the right model for what is being asked here. Certainly it is common GUI programming no matter what API is being used. –  Jan 15 '18 at 15:37
  • @jdv: _"the assumption is that Tkinter has the notion of a GUI Thread"_ that is an incorrect assumption. Tkinter is single threaded. Since the GUI thread is mostly idle, you can implement a simple timer within the main thread, without requiring the overhead of threaded programming. – Bryan Oakley Jan 15 '18 at 16:19
  • @BryanOakley well ok then. My opinion of Tkinter has been adjusted. –  Jan 15 '18 at 16:22

0 Answers0