Python - индикатор выполнения tkinter во время обработки функции - PullRequest
0 голосов
/ 30 марта 2020

Мне нужно отобразить неопределенный индикатор выполнения, чтобы указать пользователю, что что-то происходит. Я нашел много примеров, но все они управляются кнопкой, и ни один из них не показывает, как отображать индикатор выполнения во время выполнения функции. Кроме того, я хочу, чтобы индикатор выполнения отображался при запуске функции и исчезал в конце функции, без необходимости нажимать какую-либо кнопку или закрывать окно. Моя основная проблема заключается в том, что я могу отображать индикатор выполнения только при использовании функции mainloop(), и в этом случае моя программа блокируется, пока я не закрою окно. в соответствии с рекомендациями я попытался запустить индикатор выполнения в другом потоке, в настоящее время безуспешно

Это мой код:

main.py

import time
import ProgressBar

print("start")
print("sleep 5 seconds")
pb = ProgressBar.ProgBar()
time.sleep(5)
pb.stop()
print("end")

ProgressBar.py

from tkinter import *
from tkinter import ttk
from threading import thread

class ProgBar(Frame):
  def __init__(self):
    Frame.__init__(self)
    self.master.title("ProgressBar example")
    self.grid(sticky=E+W+N+S)
    self.pbar = ttk.Progressbar(self, orient="horizontal", length=300, mode="indeterminate", maximum=100)
    self.pbar.grid(row=0, column=0, pady=2, padx=2, sticky=E+W+N+S, columnspan=3)
    self.start()

  def start(self):
    def start_thread(self):
      self.pbar.start()
      self.mainloop()     
  Thread(target=start_thread, args=(self,)).start()

  def stop(self):
    self.pbar.stop()
    self.destroy()

1 Ответ

0 голосов
/ 30 марта 2020

Вам нужно вызвать функцию в потоке, отличном от того, в котором выполняется mainl oop tkinter. Это можно сделать с помощью Python s threading import довольно легко:

import threading
x = threading.Thread(target=thread_function, args=(1,))
x.start()

Когда вы запускаете ProgBar, mainl oop блокируется, прежде чем вы сможете запустить поток для выполнения вашей функции. Чтобы обойти это, прежде чем начать свой основной oop, позвоните self.after(100, self.start_thread_function). Это поставит вашу функцию в очередь, чтобы запустить поток для вашей функции через 100 мс. Вы можете настроить это время, как только вы будете sh.

Наконец, когда ваша функция будет завершена, вы можете просто вызвать функцию stop из самой функции. Обычно пользовательский интерфейс, влияющий на вызовы, совершаемые вне пользовательского интерфейса l oop, может вызвать проблемы, но из-за способа работы потоков в Python здесь не о чем беспокоиться.

...