Как вы обновляете tkinter GUI, пока выполняется долгое задание? - PullRequest
0 голосов
/ 13 марта 2020

У меня есть приложение Python, которое выполняет долгосрочную задачу, поэтому я хочу обновить метку и запустить индикатор выполнения во время выполнения задачи, а затем остановиться по завершении. Я добавил код, чтобы сделать это для действия кнопки, но код, который обновляет текст метки на «Работает ...» и запускает индикатор выполнения, никогда не работает.

import tkinter, os, time, json
from tkinter import ttk, StringVar, Tk
from tkinter.constants import HORIZONTAL

class ReportTool:

    def __init__(self, master):

        #Initialize  GUI window
        master.title("Report Tool")
        master.configure(background="white")
        master.resizable(width=False, height=False)

        #Initialize styles
        self.style = ttk.Style()
        self.style.configure("TFrame", background="white")
        self.style.configure("TLabel", background="white")
        self.style.configure("TRadiobutton", background="white")

        #Initialize frame
        self.frame = ttk.Frame(height=300, width=205)
        self.frame.pack()

        #Initialize radio buttons
        self.selected = StringVar()
        self.radio0 = ttk.Radiobutton(self.frame, text = "Dev", variable=self.selected, value="A")
        self.radio0.place(x=30, y=60)
        self.selected.set("A")
        self.radio1 = ttk.Radiobutton(self.frame, text = "Stage", variable=self.selected, value="B")
        self.radio1.place(x=30, y=90)
        self.radio2 = ttk.Radiobutton(self.frame, text = "Prod", variable=self.selected, value="C")
        self.radio2.place(x=30, y=120)

        #Initialize Labels
        #ttk.Label(self.frame, text="Records to process: " + str(self.max_c)).place(x=30, y=150)
        self.status = ttk.Label(self.frame, text="Ready")
        self.status.place(x=30, y=180)

        #Initialize Progress Bar
        self.progress_bar = ttk.Progressbar(self.frame, orient = HORIZONTAL, length = 145)
        self.progress_bar.place(x=30, y=210)
        self.progress_bar.config(mode = 'indeterminate')

        #Initialize buttons
        self.close_button = tkinter.Button(self.frame, text = "Run", bg="red", fg="white", width=8, command=lambda: self.run_tool(self.selected.get()))
        self.close_button.place(x=10, y=260)
        self.close_button = tkinter.Button(self.frame, text = "Close", bg="red", fg="white", width=8, command=self.close_callback)
        self.close_button.place(x=125, y=260)

    def timestamp(self):
        _now = int(time.time())
        tstamp = time.ctime(_now)
        return tstamp

    def working(self):
        self.status.config(text = "Working...")
        self.progress_bar.start()

    def process_data(self, endpoint_url, choice):
        self.progress_bar.start()
        log_file = '//result_log.txt'
        with open(os.curdir + '//test.json') as f:
            data = json.load(f)
            count = len(data)
            x=0             
            while x < count:
                field_id = data[x]["summary"]["id"]
                field_caption = data[x]["summary"]["caption"]
                #request logic   
#                 post_body = data[x]["query"]
#                 response = requests.get(endpoint_url, post_body)
#                 request_duration = response.elapsed.total_seconds()

                #simulate load block since requests don't work on fake URLs
                #-----
                time.sleep(2)
                #-----

                status_code = 200
                request_duration = 0.1765
                output_data = endpoint_url + "\t" + 'ID: ' + "\t" +  str(field_id) + "\t" + 'Caption: ' + "\t" +str(field_caption) + "\t" + "Status Code: " + "\t" + str(status_code) + "\t" + 'Request Duration: ' + "\t" + str(request_duration)

                with open(os.curdir + log_file, "a") as z:
                    z.write(self.timestamp()+ "\t" + output_data + "\n")
                    if x+1 == count:
                        z.write("----End Run----" + "\n")

                x += 1

    #Update button action method
    def run_tool(self, choice):
        #Attempt to set status text and start progress bar (doesn't work)
        #-----
        self.working()
        #-----
        endpoint = '/proprietaryService/queryRequest'        
        if choice == "A":
            base_url = 'https://devlink.com'
            endpoint_url = base_url + endpoint
            self.process_data(endpoint_url, choice)
        elif choice == "B":
            base_url = 'https://stagelink.com'
            endpoint_url = base_url + endpoint
            self.process_data(endpoint_url, choice)
        elif choice == "C":
            base_url = 'https://prodlink.com'
            endpoint_url = base_url + endpoint
            self.process_data(endpoint_url, choice)

        #Setting status text to done works stopping progress bar doesn't matter because it never starts...    
        self.progress_bar.stop()
        self.status.config(text = "Done")  

    #Close button action method    
    def close_callback(self):
        exit()   

def main():
    #Create application main loop
    root = Tk()
    ReportTool(root)
    root.mainloop()

if __name__ == "__main__": main()

Тест JSON для использования со скриптом:

    [
    {"summary":{"id":1,"caption":"test1"},"query":{"param1":1,"param2":2,"param3":"three"}},
    {"summary":{"id":2,"caption":"test2"},"query":{"param1":4,"param2":5,"param3":"six"}},
    {"summary":{"id":3,"caption":"test3"},"query":{"param1":7,"param2":8,"param3":"nine"}},
    {"summary":{"id":4,"caption":"test4"},"query":{"param1":10,"param2":11,"param3":"twelve"}},
    {"summary":{"id":5,"caption":"test5"},"query":{"param1":13,"param2":14,"param3":"fifteen"}}
    ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...