Python Forum
[Tkinter] Help running a loop inside a tkinter frame
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Help running a loop inside a tkinter frame
#1
I have this password manager gui app made in tkinter, which consists of a frame stack corresponding to their respective frame classes to switch between frames. Each time a frame is switched, there is a certain set of variables which get passed around the frames. page_name and username are strings whereas services and data are lists. Now status is a bool variable who's default value is False, but while switching to the current frame, its value is modified to True. Now is there a way I can implement an endless loop which keeps running while the app runs, just to check if status is True, in which case, the option menu's values get updated. or is there a method I can implement which gets called when the current frame is raised inside the window or any other way in which the program can constantly check for status value?


import tkinter as tk
from customtkinter import CTkTextbox, CTkOptionMenu

class retrieve(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        tk.Frame.__init__(self, parent, bg="black", highlightthickness=5, highlightcolor='white')
        self.controller = controller
        head = tk.Label(self, bg="black", fg="white", text="STORED DATA",
                        font=("Terminal", 32))    
        
        data_disp = CTkTextbox(self, fg_color="black", text_color="white", font=("Terminal", 22, "bold"),
                                 scrollbar_button_color="white", scrollbar_button_hover_color="white",wrap=tk.WORD,
                                 corner_radius=0, width=450, height=250, border_width=0)
        option = tk.StringVar()
        def dropdown_callback(choice):
            services = self.controller.services
            #abc = ["A", "b", "abc"]
            data = self.controller.data
            i = services.index(choice)
            result = str(data[i])
            data_disp.configure(state=tk.NORMAL)
            data_disp.delete("0.0", tk.END)
            data_disp.insert("0.0", result)
            data_disp.configure(state=tk.DISABLED)
            print("dropdown clicked:", choice)
        
        # UPDATING THE WINDOW STATUS
        status = self.controller.status
        if status:
            services = self.controller.services
            self.service_list.configure(values=services)
            print("values updated")
        # ============================
        self.service_list = CTkOptionMenu(self, fg_color="black", text_color="white", font=("Terminal", 20, "bold"), 
                                         corner_radius=0, width=450, height=36, variable=option,
                                         command=dropdown_callback, dropdown_fg_color="black", 
                                         dropdown_text_color="white", dropdown_font=("Terminal", 20, "bold"),hover=False, 
                                         button_color="black", button_hover_color="white", dropdown_hover_color="black")
        self.service_list.set(">SERVICE NAME")
        back = tk.Button(self,
                          bg="black", fg="white",
                          text='BACK', font=("Terminal", 18, "bold"),
                          command=lambda: controller.show_frame(page_name="menu", username=self.controller.username, 
                                                                 services=self.controller.services, data=self.controller.data, status=self.controller.status),
                          activebackground="black",
                          relief=tk.SOLID,
                          borderwidth=0,
                          padx=16, pady=0, cursor="hand2")
        entNote = tk.Label(self,bg="black", fg="white", text="(enter)",
                           font=("Terminal", 10))

        head.place(relx=0.5, rely=0.1, anchor=tk.CENTER)
        self.service_list.place(relx=0.1, rely=0.3, y=-10,x=-35,anchor=tk.W)
        data_disp.place(relx=0.1, rely=0.45, x=-30, y=65,anchor=tk.W)
        back.place(relx=0.5, rely=0.9, anchor=tk.CENTER)
        entNote.place(relx=0.5, rely=0.9, y=20, anchor=tk.CENTER)
        controller.exitButton(self)
        controller.homeButton(self) 
        
    def binds(self):
        self.focus_set()
        self.controller.bind('<Return>', lambda x: self.controller.show_frame(page_name="menu", username=self.controller.username, 
                                                                               services=self.controller.services, data=self.controller.data, status=self.controller.status))
Also I tried implementing like so:
while True:
            status = self.controller.status
            if status:
                services = self.controller.services
                self.service_list.configure(values=services)
                print("values updated")
                break
but on running the app, it gets freezed and then crashes.

PS: I tried tkinter binding methods too but looks like they dont work with the custom tkinter widgets I am using.
Reply
#2
(Aug-08-2023, 07:19 PM)Konstantin23 Wrote: Now is there a way I can implement an endless loop which keeps running while the app runs, just to check if status is True, in which case, the option menu's values get updated.
How does the status change? Can't you just update the option menu's values when the program changes the status? It looks like an observer pattern. Or does the status change unpredictably?
Reply
#3
tkinter has it's own loop running. You could use after to update.

example of a simple clock

import tkinter as tk
from time import strftime

class Window:
    def __init__(self, parent):
        self.parent = parent
        self.label = tk.Label(parent, text='')
        self.label.pack(expand=True, fill='both')
        self.update()

    def update(self):
        clock = strftime('%H:%M:%S')
        self.label['text'] = clock
        self.label['font'] = (None, 28, 'normal')
        self.parent.after(1000, self.update)

if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('300x200+200+200')
    Window(root)
    root.mainloop()
Konstantin23 likes this post
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#4
(Aug-08-2023, 07:39 PM)menator01 Wrote: tkinter has it's own loop running. You could use after to update.

example of a simple clock

import tkinter as tk
from time import strftime

class Window:
    def __init__(self, parent):
        self.parent = parent
        self.label = tk.Label(parent, text='')
        self.label.pack(expand=True, fill='both')
        self.update()

    def update(self):
        clock = strftime('%H:%M:%S')
        self.label['text'] = clock
        self.label['font'] = (None, 28, 'normal')
        self.parent.after(1000, self.update)

if __name__ == '__main__':
    root = tk.Tk()
    root.geometry('300x200+200+200')
    Window(root)
    root.mainloop()

Thank you so much! this was exactly the kind of solution I was looking for, implementing a self updating function.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] TKinter Remove Button Frame Nu2Python 8 1,027 Jan-16-2024, 06:44 PM
Last Post: rob101
  Using Tkinter inside function not working Ensaimadeta 5 5,089 Dec-03-2023, 01:50 PM
Last Post: deanhystad
  tkinter destroy label inside labelFrame Nick_tkinter 3 4,575 Sep-17-2023, 03:38 PM
Last Post: munirashraf9821
  tkinter mapview in a frame janeik 2 1,342 Jun-22-2023, 02:53 PM
Last Post: deanhystad
  [Tkinter] Have tkinter button toggle on and off a continuously running function AnotherSam 5 5,051 Oct-01-2021, 05:00 PM
Last Post: Yoriz
  [Tkinter] Trouble changing Font within tkinter frame title AnotherSam 1 4,155 Sep-30-2021, 05:57 PM
Last Post: menator01
  [Tkinter] Redirecting all print statements from all functions inside a class to Tkinter Anan 1 2,661 Apr-24-2021, 08:57 AM
Last Post: ndc85430
  tkinter frame camera opencv Nick_tkinter 9 5,483 Mar-21-2021, 06:41 PM
Last Post: Nick_tkinter
  align frame inside canvas ro_btz 1 1,861 Sep-11-2020, 04:38 PM
Last Post: Larz60+
  [Tkinter] Tkinter delete values in Entries, when I'm changing the Frame robertoCarlos 11 5,879 Jul-29-2020, 07:13 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020