简体   繁体   中英

widget in sub-window update with real-time data in tkinter python

I've tried using the after/time.sleep to update the treeview, but it is not working with the mainloop.

My questions are:

  • How can I update the treeview widget with real-time data?
  • And is there a way that I can change all treeview children simultaneously? (I don't want to delete all children and insert again)

Script 1:

class mainwindow(tk.Tk):
    #Initalize main window
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

       #use to shift frames
       ....
 if __name__ == "__main__":
    ...
    app = mainwindow()
    app.geometry("1920x1080")
    app.mainloop()

Script 2:

class Page_one(tk.Frame):
    def __init__(self, parent, controller):
        mainframe=tk.Frame.__init__(self, parent)
        self.controller = controller

        #treeview widget attached to page_one
        tree1=Treeviews(...)
        tree1.place(x=880,y=25)

#Question1: How can I update the treeview widget with real-time data? 
#Question2: is there a way that I can change all treeview children simuteniously? (I dont want to delete all children and insert again)

My question is: may someone show me a structure that I could use for updating widgets in my second script.

You can modify a treeview widget with the item method:

tree.item(<item id>, text='new text', values=(...))

The item's id is returned upon item creation. And you can change all the treeview children by putting the above code in a for loop:

for item in tree.get_children(<parent>):
    tree.item(item, text='new text', values=(...))

tree.get_children(<parent>) returns the children of the item ('' for the root of the tree).

From your question, I understand that you have some separate process that generates data and you want to periodically update the treeview content with the new data generated. Using time.sleep would freeze the mainloop, so you should use the after tkinter method: tree.after(<time in ms>, callback, *args) will wait for the given time and then execute callback(*args) . If you want a periodical callback, the trick is to call again after inside callback , eg:

def callback(x, y):
    # do something with x and y ...
    tree.after(2000, callback, x, y)

So once you launch callback(0, 2) , it will be executed every 2s.

Here is an example with a treeview:

import tkinter as tk
from tkinter import ttk

def update_item(item):
    val = int(tree.item(item, 'value')[0])
    tree.item(item, values=(val + 1,))
    root.after(1000, update_item, item)

def update_all_items():
    for item in tree.get_children():
        tree.item(item, values=(0,))

root = tk.Tk()
tree = ttk.Treeview(root, columns=('value'))
tree.heading('value', text='Value')

for i in range(5):
    tree.insert('', 'end', 'item%i' % i, text='item %i' % i, values=(i,))

update_item('item0')

tree.pack()
ttk.Button(root, text='Update', command=update_all_items).pack()

root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM