I'm trying to update a Label with a method that is called via a scheduler process, but when i try to configure the label, the app crashes with a segmentation fault
This is my script
class Gui():
def __init__(self):
app = Tk()
self.initialize_user_interface()
def initialize_user_interface(self):
self.title("Title")
self.geometry(f"{1100}x{700}")
self.sidebar_frame = Frame(self)
self.sidebar_frame.grid()
self.my_label = Label(self.sidebar_frame)
self.my_label.grid()
thread = threading.Thread(target=self.start_schedule, daemon=True)
thread.start()
def start_schedule(self):
schedule.every(30).seconds.do(lambda: self.update_label())
def update_label(self):
self.my_label=configure(text="Custom Text")
if __name__ == "__main__":
app = Gui()
app.mainloop()
I tried to call the method inside the class, using the self but i keep getting the error of segmentation fault
Here's a working example that updates the text of the Label
widget to a random number every 3 seconds. It demonstrates how to handle this using tkinter's after
method rather than relying on threading
and other modules.
I've also fixed the issue preventing the Frame
and Label
from appearing by passing them both to pack()
, and I fixed the typo in self.my_label.configure
from tkinter import *
from random import randint # for demonstration purposes
class Gui(Tk): # inherit from Tk in your main app class
def __init__(self) -> None:
super().__init__() # initialize Tk (your inherited superclass)
self.initialize_user_interface()
self.update_label() # begin label updates
# if you'd rather start the label updates after a delay, do this instead:
# self.after(30_000, self.update_label)
# you can set whatever delay you like here
def initialize_user_interface(self) -> None:
self.title("Title")
self.geometry(f"{1100}x{700}")
self.sidebar_frame = Frame(self)
self.sidebar_frame.pack()
self.my_label = Label(self.sidebar_frame)
self.my_label.pack()
def update_label(self) -> None:
"""Set the label to a random value for demonstration"""
self.my_label.configure(text=randint(0, 100))
# repeat this function after however many mS
self.after(3000, self.update_label)
if __name__ == "__main__":
app = Gui()
app.mainloop()
As an aside, you generally want to avoid "star" imports, like from tkinter import *
because they can lead to a problem called "namespace pollution" (think about what would happen if some other module you were using also had a class named Label
). Typically, you'll see import tkinter as tk
, and any related classes are then instantiated with tk
as a prefix like tk.Label
, tk.Button
, etc.