В GUI ваш код в основном guest в событии GUI toolkit l oop (mainloop
в tkinter).
Так что вы не можете иметь длительное выполнение l oop в программе GUI; Вы должны структурировать свой код по-другому. Например, скажем, что у вас есть oop, как это;
# *Long* list of data
data = [ ... ]
# storage for results
result = []
for item in data:
rv = process(item)
result.append(rv)
Если бы вы запускали такое al oop в GUI программе, это прервало бы поток событий. По сути, он замораживает GUI и рендеринг не отвечает.
Так что в tkinter GUI вам придется выполнять вычисления в обработчике тайм-аута. Ниже приведен набросок принципа разделения длительной работы на маленькие кусочки, которые можно обработать внутри события GUI -l oop.
import tkinter as tk
from tkinter import messagebox
# *Long* list of data
data = [ ... ]
# storage for results
result = []
index = 0
def iteration():
'''Handles one iteration in the event loop.'''
rv = process(data[index])
result.append(rv)
index += 1
if index < len(data):
root.after(100, iteration)
else:
messagebox.showinfo('Calculations', 'Finished!')
def create_UI():
# Create and place the widgets here.
pass
if __name__ == '__main__':
root = tk.Tk(None)
widgets = create_UI(root)
root.after(100, iteration)
root.mainloop()
Как видите, ваш В этом случае код должен иметь другую структуру.
Обратите внимание, что на CPython только один поток может одновременно выполнять Python байт-код, поэтому использование потоков не является действительно хорошее решение для этого. Тем более что многие GUI наборы инструментов не являются поточно-ориентированными, поэтому вы должны только вызывать GUI функций из одного потока.
Другим решением было бы запустить вычисление в другая программа. Эта программа может затем связаться с GUI с помощью Queue
. Вы должны будете использовать функцию тайм-аута в GUI для регулярного отслеживания очереди и отображения результатов. Это не простое решение, но может предложить более высокую производительность, если вы можете разделить вычисления на несколько процессов.
Редактировать :
Обратите внимание, что в первом решении, каждая итерация должна занимать относительно небольшое количество времени, например, 100 мс. Если бы это заняло намного больше времени, GUI чувствовал бы, что он не отвечает. Если это невозможно, используйте второе решение (отдельную программу).
У меня нет удобной ссылки на эту проблему. Но простой шаблон выглядит следующим образом:
Вы пишете две программы.
Первая программа - это простой Python скрипт, который выполняет свои вычисления в обычном порядке. л oop. Единственная особенность заключается в том, что в конце каждой итерации записывает в файл значения T, Ca, T c и q.
Вторая программа - это Python Программа tkinter, использующая метод after
для проверки времени модификации вышеупомянутого файла. Если он обнаруживает, что файл изменился, он читает файл и обновляет его отображение.
Этот подход полностью устраняет проблемы выполнения вычислений и отображения промежуточных результатов, то есть вы можете написать и тестируем их отдельно.
Общее название этого решения, я думаю, называется «наблюдателем за файлами». Такое решение встречается настолько часто, что я не могу вспомнить, где я это говорю первым.