I am new to python/tkinter, running python 3.8. I have run into an issue where I need to start a thread/process that will update pb1(progressbar) slowly while CSF.addOrders is active. CSF.addOrders runs on a server and takes between 10 sec and 5 min depending on # of orders. It causes the app to show "Not Responding" even though it is working. Also, the time delay makes it so the app users don't know that the program is still running as progressbar(pb1) doesn't update.
I have simplified the code I am using to show the critical segments. I need pb1(progressbar) to slowly update while CSF.addOrders is running and for it to terminate as soon as CSF.addOrders is completed. I have read a bunch of the posts on Not Responding but have been unable to figure out what to do. Beacause of the use of frames and classes it does not seem to have an answer already provided. Any help/guidance would be very much appreciated.
This is the Code that Fixes tkinter GUI "Not Responding" and allows the progressbar to continue until the Server side function is completed.
import tkinter as tk
import tkinter.ttk as ttk
import ClientServer_Functions as CSF
import threading
import queue
import logging
import time
# Log File
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s:%(message)s', datefmt='%Y-%m-%d %H:%M:%S')
# create the handlers and call logger.addHandler(logging_handler)
if not logger.handlers:
file_handler = logging.FileHandler('GUI_Logger.log')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
logger.propagate = False
class sample(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.shared_data = {
"fName": tk.StringVar(), # userInfo[0][0]
"username": tk.StringVar(), # userInfo[0][1]
"password": tk.StringVar(), # userInfo[0][2]
"custSym": tk.StringVar(), # userInfo[0][3]
"email": tk.StringVar(), # userInfo[0][4]
"sPath": tk.StringVar(), # userInfo[0][5]
"FTP_User": tk.StringVar(), # userInfo[0][6]
"FTP_Password": tk.StringVar(), # userInfo[0][7]
"fType": tk.StringVar()
}
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
global bgColor
bgColor = "black"
self.frames = {}
for F in (Trade, blank): #there are other frames I create that are not listed
frame = F(container, self)
self.frames[F] = frame
frame.config(bg=bgColor)
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Trade)
def get_page(self, page_class):
return self.frames[page_class]
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class Trade(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
tk.Label(self, bg=bgColor).pack()
tk.Label(self, text="TRADES", bg=bgColor, fg="yellow").pack(pady=20)
tk.Button(self, text="Orders", command=lambda: [self.setFType("Orders"), self.files()]).pack(pady=10)
self.statusbar = tk.Label(self)
self.statusbar.pack(side=tk.BOTTOM, fill=tk.X)
def setFType(self, fType):
self.controller.shared_data["fType"].set(fType)
def aOrders(self, ls):
l = ls[0]
print("starting t1")
time.sleep(1)
result, msg, FTP_outFile = CSF.addOrders(l,"u", "p", "fp", "sp", "c")
return result, msg, FTP_outFile
def files(self):
fType = self.controller.shared_data["fType"].get()
self.statusbar['text'] = "Running..."
pb1 = ttk.Progressbar(self, orient=tk.HORIZONTAL, length=250, mode='determinate')
pb1['value'] += 10
pb1.place(relx=.25, rely=.88)
que = queue.Queue()
t1 = threading.Thread(target = lambda q, arg : q.put(self.aOrders(arg)), args = (que, [logger, 2]))
t1.start()
for x in range(100):
if t1.is_alive():
print("update pb1")
pb1['value'] += 2
tk.Tk.update(self)
time.sleep(1)
else:
print(que.get())
break
print("do balance of program...")
class blank(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
if __name__ == "__main__":
app = sample()
app.geometry("500x500+500+150")
app.mainloop()
from Using class and frames with tkinter getting app "Not Responding" msg in Titlebar. Need Multithreading/Processing assistance to resolve
No comments:
Post a Comment