Как управлять чувствительностью окна Tkinter при запуске большого количества внутренних потоков - PullRequest
0 голосов
/ 03 декабря 2018

Я разрабатываю приложение, которое управляет множеством объектов, наследуемых от потоков.По некоторым причинам я создал пользовательский интерфейс с библиотекой Tkinter, который будет печатать эволюцию моих объектов.Для связи с моим окном у меня есть другой поток, который управляет всем бэкэнд-приложением и передает данные в окно.

Но я борюсь с проблемой.Мое окно все еще отзывчиво, но реагирует очень долго.Поэтому я не могу видеть результаты в режиме реального времени.Я попытался описать мою проблему следующим образом:

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()

Поэтому мой пользовательский интерфейс создает объект bigThread и запускает его, когда я нажимаю кнопку запуска.Объект bigThread запускает сотню объектов littleThread, которые будут выполнять дорогую вычислительную функцию.В результате мое окно все еще застревало до тех пор, пока не появилось какое-то освежение.Я мог бы иметь достаточно закусок или времени, достаточного для того, чтобы окно реагировало на максимально короткое время отклика.

(я уже читал похожие вопросы, но у меня они разные, потому что окно все еще отзывчиво, но недостаточно)

Есть идеи, как это сделать?Заранее благодарим за помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...