I am trying to update a treeview every second from a database with clients and ping time status, if the successful ping was before some:X time the row will be red(or odd red to distinguish).
update_tree
always is running with and sleeping 1 sec between each loop.
Also instead of deleting all the children i insert to each obj iid
the values and tags
Here is update_tree function:
def update_tree(self, tree):
index = {'id': 0, 'addr': 1, 'ping': 2}
self.iid_count = 0
while True:
count = 0
clients = DB().get_curs().execute("SELECT ID,ADDR,PING FROM CLIENTS").fetchall()
childrens = tree.get_children('')
# update whole treeview if bool table or bool ping true or no childrens
if childrens == ():
for client in clients:
tree.insert('', END, iid=client[index['id']], text='', values=(
"CON", client[index['ping']], client[index['addr']], client[index['id']], self.iid_count),
tags=('blue',))
self.iid_count += 1
self.db_row_count = DB().get_curs().execute("SELECT COUNT(*) FROM CLIENTS").fetchone()
else:
for client in clients:
client_ping_time = self.pinger.str_to_time(client[index['ping']])
# even rows
if count % 2 == 0:
# if the time in db for ping + 5 sec is bigger than now meaning it was created in past 3 secs
if (client_ping_time + timedelta(seconds=3) > datetime.now()):
tree.item(client[index['id']], values=(
"CON", client[index['ping']], client[index['addr']], client[index['id']], count),
tags=('seccsess_even',))
# if last seccsessful ping was before 5 sec
else:
tree.item(client[index['id']], values=(
"CON", client[index['ping']], client[index['addr']], client[index['id']], count),
tags=('fail_even',))
# odd rows
else:
if (client_ping_time + timedelta(seconds=3) > datetime.now()):
tree.item(client[index['id']], values=(
"CON", client[index['ping']], client[index['addr']], client[index['id']], count),
tags=('seccsess_odd',))
else:
tree.item(client[index['id']], values=(
"CON", client[index['ping']], client[index['addr']], client[index['id']], count),
tags=('fail_odd',))
count += 1
self.db_row_count = DB().get_curs().execute("SELECT COUNT(*) FROM CLIENTS").fetchone()
time.sleep(1)
After having some more experience with ui's (in Qt though) I can clearly see that there are two main reasons why the window freezes for each update.
time.sleep
while running an event loop (tkinter have an event loop just like any other ui framework) if you do so, the application just wont handle events therefore will freezeAs suggested by @derek I need to drop the while loop in the function ans call it with after
to add this to the event loop like so:
iid_count = 0
index = {'id': 0, 'addr': 1, 'ping': 2}
def update_tree(self, tree):
count = 0
ping_update_bool = self.pinger.ping_clients_db()
clients = DB().get_curs().execute("SELECT ID,ADDR,PING FROM CLIENTS").fetchall()
childrens = tree.get_children('')
# update whole treeview if bool table or bool ping true or no childrens
if childrens == ():
for client in clients:
tree.insert('', END, iid=client[self.index['id']], text='', values=(
"CON", client[self.index['ping']], client[self.index['addr']], client[self.index['id']], self.iid_count),
tags=('blue',))
self.iid_count += 1
self.db_row_count = DB().get_curs().execute("SELECT COUNT(*) FROM CLIENTS").fetchone()
else:
for client in clients:
client_ping_time = self.pinger.str_to_time(client[self.index['ping']])
# even rows
if count % 2 == 0:
# if the time in db for ping + 5 sec is bigger than now meaning it was created in past 3 secs
if (client_ping_time + timedelta(seconds=3) > datetime.now()):
tree.item(client[self.index['id']], values=(
"CON", client[self.index['ping']], client[self.index['addr']], client[self.index['id']], count),
tags=('seccsess_even',))
# if last seccsessful ping was before 5 sec
else:
tree.item(client[self.index['id']], values=(
"CON", client[self.index['ping']], client[self.index['addr']], client[self.index['id']], count),
tags=('fail_even',))
# odd rows
else:
if (client_ping_time + timedelta(seconds=3) > datetime.now()):
tree.item(client[self.index['id']], values=(
"CON", client[self.index['ping']], client[self.index['addr']], client[self.index['id']], count),
tags=('seccsess_odd',))
else:
tree.item(client[self.index['id']], values=(
"CON", client[self.index['ping']], client[self.index['addr']], client[self.index['id']], count),
tags=('fail_odd',))
count += 1
self.db_row_count = DB().get_curs().execute("SELECT COUNT(*) FROM CLIENTS").fetchone()
tree.after(1000, self.update_tree, tree)