Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing widget's reference to a function

Tags:

python

tkinter

In the following Python application, my main Tkinter-based GUI window has some some buttons (which in turn call some functions) and text widgets. The text widgets are to be updated from the function called by pressing the buttons.

I tried sending the text to function but I can't see the updated values in the text in a sequential order. Rather it is first completing the function (or loop) and then at the end it updates all the values together. I want to see them one by one as the corresponding instruction is executed.

from Tkinter import *
import Tkinter as tk
from functools import partial
import time

class mainWindow:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)

        self.stat0 = tk.Text(self.frame,bg='cyan', font=("Helvetica", 10), width = 8, height = 1)
        self.stat0.grid(row=2, column=0, sticky=W)    
        self.b0 = tk.Button(self.frame,bg='black',fg='white',text='LOAD',font=("Helvetica", 8),command=lambda:self.loadStatus(self.stat0))
        self.b0.grid(row = 1, column = 0, sticky=W)

        self.frame.grid()


    def loadStatus(self,stat):
        stat.insert(END,5)
        time.sleep(1)
    #   stat.delete(1.0,END)
        stat.insert(END,"hi")
    #   stat.delete(1.0,END)
        time.sleep(1)
        stat.insert(END,0)

if __name__ == '__main__':
    #main()
    root = tk.Tk()
    app = mainWindow(root)
    root.mainloop()

Here, on pressing the load button, I can see all the values (that are assigned sequentially) at one go after the completion of function and after the delay inserted.

Please help me with updating the text entry one by one as per executed instruction.

like image 909
Ashish Sharma Avatar asked Jan 31 '26 09:01

Ashish Sharma


1 Answers

You should use after to do some time triggered events in tkinter. I changed your code to use it:

from Tkinter import *
import Tkinter as tk
from functools import partial

class mainWindow:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)

        self.stat0 = tk.Text(self.frame,bg='cyan',
                             font=("Helvetica", 10), width = 8, height = 1)
        self.stat0.grid(row=2, column=0, sticky=W)
        self.b0 = tk.Button(self.frame,bg='black',fg='white',text='LOAD',
                            font=("Helvetica", 8),command=self.loadStatus)
        self.b0.grid(row = 1, column = 0, sticky=W)

        self.frame.grid()


    def loadStatus(self):

        self.stat0.insert(END, "hi")
        self.frame.after(1000, self.loadStatus)



if __name__ == '__main__':
    #main()
    root = tk.Tk()
    app = mainWindow(root)
    root.mainloop()

The idea is that loadStatus is called "recursively" by after. Now it works forever, but you can add some counters etc, to check when the recursive calls should stop. Hope this helps.

like image 185
Marcin Avatar answered Feb 01 '26 22:02

Marcin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!