Почему мой индикатор выполнения не отображается в tkinter

#tkinter

#tkinter

Вопрос:

Я пытаюсь закодировать экран загрузки для моего приложения Tkinter и пытаюсь создать анимированный индикатор выполнения. Я следовал руководству и адаптировал код в свою собственную версию. Сначала, когда я нажимаю «Выполнить», коды работают нормально, но как только я добавил функцию для анимации индикатора выполнения, индикатор выполнения вообще перестал отображаться. Код, который я получил, выглядит следующим образом:

 from tkinter import *
import random
import time
import sqlite3
from tkinter import simpledialog
from tkinter import messagebox
from tkcalendar import *
from tkinter import ttk
import math
from PIL import Image, ImageTk
import winsound

#--------------Frames--------------------------
class VendingApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self._frame = None
        self.switch_frame(Loading)

    def switch_frame(self, frame_class):
        #Destroys current frame and replaces it with a new one.
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class Loading(Frame):    
    def __init__(self, master):
        Frame.__init__(self, master)


    def load():
        for x in range(100):
            Loading_bar['value']  = 1
            root.update_idiletasks()
            time.sleep(1)
##            

        Loading_bar = ttk.Progressbar(self, orient = HORIZONTAL,
                                      length = 500, mode = 'determinate')
        Loading_bar.pack(pady = 200)


        load()
        
#---------------------------------------------------------------------------------------




#----------------------------------------------------------------------------------------
if __name__ == "__main__":
    root = VendingApp()
    #Sets the size of the window
    root.geometry("1024x768")
    #Renames the TITLE of the window
    root.title("Vending machine")
    root.geometry("1024x768")
    root.resizable(False, False) 


    root.mainloop()
 

Я создал отдельный файл, чтобы попытаться проверить, будет ли он работать только с tkinter и без класса с этим кодом:

 from tkinter import ttk
from tkinter import*
import time

root = Tk()

def load():
    for x in range(100):
        time.sleep(1)
        Loading_bar['value']  = 1
        root.update_idletasks()
   
    None


Loading_bar = ttk.Progressbar(root, orient = HORIZONTAL,
                            length = 500, mode = 'determinate')
Loading_bar.pack()

load()

root.mainloop()
 

И в результате каждый раз, когда я запускаю его, программа загружается бесконечно. Может кто-нибудь, пожалуйста, скажите мне, что я сделал не так, пожалуйста? Нет необходимости указывать правильный код, достаточно указать error / s и указать, как это исправить, хотя правильный код будет очень оценен. Спасибо!

Ответ №1:

sleep() Функция приостановит выполнение, а также обновит графический интерфейс.

Попробуйте after() вместо этого использовать функцию. Он планирует load() функцию на потом, но не влияет на остальную часть вашей программы:

 from tkinter import ttk
from tkinter import*
import time

root = Tk()

def load():
    current_value = Loading_bar.cget('value')
    if current_value < 100:
        root.after(10, load)
    Loading_bar.config(value=current_value 1)

Loading_bar = ttk.Progressbar(root, orient = HORIZONTAL,
                            length = 500, mode = 'determinate')
Loading_bar.pack()

load()

root.mainloop()
 

Добавление нового примера

Я добавил новый пример, который является модификацией вашего исходного кода. Я создаю индикатор выполнения в __init__() функции Loading() класса. После того, как индикатор выполнения достигает 100, индикатор выполнения удаляется, но не уничтожается.

 from tkinter import *
from tkinter import ttk

class VendingApp(Tk):
    def __init__(self):
        Tk.__init__(self)
        self._frame = None
        self.switch_frame(Loading)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class Loading(Frame):    
    def __init__(self, master):
        Frame.__init__(self, master)
        self.Loading_bar = ttk.Progressbar(self, orient=HORIZONTAL,
                                           length=500, mode='determinate')
        self.Loading_bar.pack(pady=200)
        self.load()

    def load(self):
        current_value = self.Loading_bar.cget('value')
        if current_value < 100:
            self.after(10, self.load)
        else:
            self.Loading_bar.pack_forget()  # Removing widget from frame
        self.Loading_bar.config(value=current_value 1)

if __name__ == "__main__":
    root = VendingApp()
    root.geometry("1024x768")
    root.mainloop()
 

Это работает лучше?

Комментарии:

1. Большое вам спасибо за ваш ответ:) строки кода для устранения неполадок работают прекрасно, но когда я адаптирую его в приложение, проблема все еще сохраняется, и я не понимаю почему.

2. Я добавил новый пример, изменив ваш исходный код. Это лучше иллюстрирует решение?