Tkinter - Создание отзывчивого GUI с индикатором выполнения - PullRequest
0 голосов
/ 03 апреля 2020

Используя PyGubu (инструмент для создания интерфейсов Tkinter), я получил следующее GUI: enter image description here

Текущая ситуация:

Когда я нажимаю кнопку " Создать ", функция вызывается. Эта функция занимает довольно много времени, и графические интерфейсы просто заморожены. Поскольку я хотел бы сохранить графический интерфейс и функциональную часть как можно более отделенными, я не хочу обновлять индикатор выполнения или интерфейс в целом из функции, которую я вызываю

Желаемая ситуация

Лучшим вариантом для меня было бы решение без использования потоков: я хотел бы, чтобы после нажатия кнопки «Создать» моя функция работала, а индикатор выполнения обновлялся сам (просто чтобы показать отзыв пользователю и сообщить ему «Смотри, я что-то делаю»), и интерфейс остается отзывчивым, поэтому пользователь может фактически взаимодействовать с ним, пока функция fini sh.

Текущие попытки

Я пытался решить эту проблему использование потоков:

#I have this code in my main.py:
from threading import Thread 
from queue import Queue, Empty
my_queue=Queue()

#And this is a simplified version of the Command of the "Create" Button:
def create_command(self):
    #Show the progress bar and start it
    self.show_item(self.progress)
    self.progress.start()

    #Run the big function
    thrd = Thread(target = my_big_function, args=(some_arguments, my_queue))
    thrd.start()


    do_retry = True
    while do_retry:                      #Repeat until you have a result
        try:
            result = my_queue.get(False) #If you have a result, exit loop. Else, throw Empty
            do_retry = False
        except Empty:                    #Queue is still empty
            self.progress_var.set(self.progress_var.get()+1)
            sleep(0.05)
            self.mainwindow.update()     #Update the progress bar

    q.task_done()                        
    self.progress.stop()

Проблема текущей попытки

Поскольку я не привык работать с потоками, я сталкиваюсь с двумя проблемами:

  1. В некоторых запусках (не во всех, только в некоторых) у меня есть RuntimeError с указанием

    RuntimeError: основной поток не находится в основном цикле, я пытался преодолеть это, глядя на другие вопросы В StackOverflow, но теперь это происходит случайно, и я не знаю, как этого избежать. Модуль mtTinker больше не поддерживается для python 3.x (есть неопределенная попытка, полная задач и крови)

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

Итак

Как я могу получить желаемый результат? Заранее спасибо

1 Ответ

0 голосов
/ 03 апреля 2020

Вы можете попробовать добавить root.update() внутри вызываемой функции, внутри основной l oop. Надеюсь, что это полезно!

...