0

I'm trying to build a clock with python and tkinter but I don't know how to make the tkinter UI update every second. Right now it shows the time on the UI but it doesn't updtade. I have tried to make a loop with .after but python gives the following error:

RecursionError: maximum recursion depth exceeded while calling a Python object.

How do I fix this?

Code:

import datetime
from tkinter import *
from tkinter.ttk import *

class clock:
    def __init__(self):
        pass

        
    def get_hour(self):
        self.date_time = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S/%p")
        self.date, self.time1 = self.date_time.split()
        self.time2, self.time3 = self.time1.split('/')
        self.hour, self.minutes, self.seconds =  self.time2.split(':')
    
    def format_hour(self):
        if int(self.hour) > 12 and int(self.hour) < 24:
                self.time = str(int(self.hour) - 12) + ':' + self.minutes + ':' + self.seconds + ' ' + self.time3
                return self.time
        else:
                self.time = self.time2 + ' ' + self.time3
                return self.time
                
                
    def execute(self):
        while True:
            self.get_hour()
            return self.format_hour()
            
class clock_ui:
    def __init__(self, the_window):
        self.the_window = the_window
        self.the_window.title("Clock")
        self.the_window.geometry('1300x550')
        self.tabs()
        self.update_ui()
        

# Adds the tabs for the user to select on the interface:
    def tabs(self):
        self.tabs_control = Notebook(self.the_window)
        self.clock_tab = Frame(self.tabs_control)
        self.alarm_tab = Frame(self.tabs_control)
        self.stopwatch_tab = Frame(self.tabs_control)
        self.timer_tab = Frame(self.tabs_control)
        self.tabs_control.add(self.clock_tab, text="Clock")
        self.tabs_control.add(self.alarm_tab, text="Alarm")
        self.tabs_control.add(self.stopwatch_tab, text='Stopwatch')
        self.tabs_control.add(self.timer_tab, text='Timer')
        self.tabs_control.pack(expand = 1, fill ="both")

        # Adds the looks on the clock tab:
        self.time_label = Label(self.clock_tab, font = 'calibri 40 bold', foreground = 'black')
        self.time_label.pack(anchor='center')
        self.date_label = Label(self.clock_tab, font = 'calibri 40 bold', foreground = 'black')
        self.date_label.pack(anchor='s')
        
    def update_ui(self):
        self.time_label.config(text = clock().execute())
        # self.date_label.config(text= date)
        # self.time_label.after(1000, self.update_ui())
        
app = Tk()
my_clock = clock_ui(app)
app.mainloop()
Michael M.
  • 10,486
  • 9
  • 18
  • 34
  • There are dozens of questions about timers and clocks with tkinter. Have you searched through them to see how they apply? – Bryan Oakley Oct 05 '22 at 03:18

1 Answers1

0

In line 59, you must declared variable. And line 60, then add string to self.date_label.config.

def update_ui(self):
    string = self.time_label.config(text = clock().execute())
    self.date_label.config(text=string)
    self.time_label.after(1000, self.update_ui)

You will see second second pass continuously.

Result output:

enter image description here

toyota Supra
  • 3,181
  • 4
  • 15
  • 19
  • This doesn't look right. Every time `update_ui` is created it creates a new instance of `clock` and creates a new infinite loop. – Bryan Oakley Oct 05 '22 at 14:48
  • This did in fact solve the problem, now it updates normally. But Bryan's comment actually worried me, is it important to fix that? – Guilherme Bailer Motta Oct 05 '22 at 21:41
  • The while loop inside `execute()` is useless and not necessary as it will return on first iteration. For this answer, `string` is always `None` as it is the result of `.config()`. – acw1668 Oct 06 '22 at 00:28