I'm developing an application that manages a lot of objects inheriting from threading.Thread. For some some reasons, I created a user interface with the Tkinter library that would print the evolution of my objects. To communicate with my window, I have another thread that manages all the backend application and will transmit the data to the window.
But I'm struggling on a problem. My window still responsive but takes a huge amount of time to react. So I'm not able to see the results in real time. I tried to summarize my problem as follows:
from threading import Thread
from tkinter import *
from time import sleep
from random import random
class UItest(Tk):
def __init__(self):
Tk.__init__(self)
# Graphic elements of the window
self.startButton = Button(master=self,width=3,text="Start/stop",command=self.start_stop)
self.title = Label(master=self,text="Nb of iterations")
self.name_1 = Label(master=self, text="Thread 1 :")
self.name_2 = Label(master=self, text="Thread 2 :")
self.name_3 = Label(master=self, text="Thread 3 :")
self.name_4 = Label(master=self, text="Thread 4 :")
self.name_5 = Label(master=self, text="Thread 5 :")
self.value_1 = Label(master=self, text="0")
self.value_2 = Label(master=self, text="0")
self.value_3 = Label(master=self, text="0")
self.value_4 = Label(master=self, text="0")
self.value_5 = Label(master=self, text="0")
self.startButton.grid(row=0,sticky='nsew')
self.title.grid(row=1, sticky='nsew')
self.name_1.grid(row=2, column=0, sticky='w')
self.value_1.grid(row=2, column=1, sticky='w')
self.name_2.grid(row=3, column=0, sticky='w')
self.value_2.grid(row=3, column=1, sticky='w')
self.name_3.grid(row=4, column=0, sticky='w')
self.value_3.grid(row=4, column=1, sticky='w')
self.name_4.grid(row=5, column=0, sticky='w')
self.value_4.grid(row=5, column=1, sticky='w')
self.name_5.grid(row=6, column=0, sticky='w')
self.value_5.grid(row=6, column=1, sticky='w')
# Computing elements
self.computingThread=bigThread()
self.computingThread.connectToUItest(self.getValues)
self.state = 0
self.mainloop()
def getValues(self,val1,val2,val3,val4,val5):
self.value_1.config(text=val1)
self.value_2.config(text=val2)
self.value_3.config(text=val3)
self.value_4.config(text=val4)
self.value_5.config(text=val5)
def start_stop(self):
if self.state==0:
self.computingThread.start()
self.state=1
print("start")
else:
self.computingThread.exitflag=1
print("stop")
class bigThread(Thread):
def __init__(self):
Thread.__init__(self)
self.exitflag=0
self.thread_list=[]
for i in range(100):
thread=littleThread()
thread.ID=i
self.thread_list.append(thread)
def connectToUItest(self, func):
self.updateUI = func
def run(self):
for i in range(100):
self.thread_list[i].start()
while self.exitflag==0:
self.updateUI(self.thread_list[0].nb_iteration,
self.thread_list[1].nb_iteration,
self.thread_list[2].nb_iteration,
self.thread_list[3].nb_iteration,
self.thread_list[4].nb_iteration)
sleep(0.01)
for i in range(100):
self.thread_list[i].exitflag = 1
class littleThread(Thread):
def __init__(self):
Thread.__init__(self)
self.nb_iteration=0
self.exitflag=0
self.ID=0
def run(self):
while self.exitflag==0:
self.nb_iteration+=1
self.doExpensiveStuff()
sleep(random()*3)
print("Thread", self.ID, "exits")
def doExpensiveStuff(self):
size=200
a = []
b = []
for i in range(1):
for row_index in range(size):
a_row=[]
b_row=[]
for col_index in range(size):
a_row.append(random())
b_row.append(random())
a.append(a_row)
b.append(b_row)
return expensiveProduct(a,b)
def expensiveProduct(a,b):
for i in range(len(a)):
for j in range(len(a)):
a[i][j]=a[i][j]*b[i][j]
return a
App = UItest()
So my UI creates a bigThread object and start it when I press start button. The bigThread object will launches a hundred littleThread objects that will run an expensive computation function. As a result, my window still stuck until sometimes, there is kind of refreshment. I would be able to have enough refreshments or enough time allow to the window to make responsive time the shortest as possible.
(I already read related questions but mine's differ because the window still responsive but not enough)
Any idea how to do that? Thank's in advance for your help