Reputation: 21
I am facing issue with the progress bar. In the go_ahead function() I am actually calling another python program which processes two files for fuzzy matching. For this, I have just replaced it with a sleep(5) to show minimal code. The progress bar gets stuck and when the program completes, it starts scrolling. It also remains freezed when the program starts. Can someone please help resolving this issue of progress bar?
from tkinter import filedialog
from tkinter import ttk
import time as T
import datetime
import tkinter.messagebox as tkMessageBox
from os import system
import os
import threading
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
fname1=[]
fname2=[]
root = Tk.Tk()
root.wm_title("Fuzzy Match Wizard")
root.resizable(False, False)
window_height = 600
window_width = 1000
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x_cordinate = int((screen_width/2) - (window_width/2))
y_cordinate = int((screen_height/2) - (window_height/2))
root.geometry("{}x{}+{}+{}".format(window_width, window_height, x_cordinate, y_cordinate))
#root.configure(background='PaleGreen4')
root.configure(borderwidth=6)
root.configure(relief='ridge')
root.configure(highlightcolor="black")
root.configure(takefocus="15")
root.configure(width="5")
def go_ahead():
root.update()
T.sleep(10)
root.update()
tkMessageBox.showinfo(title="Greetings", message="Fuzzy Match Completed")
def run_progressbar():
global p
global p_Lab
p = ttk.Progressbar(root,orient="horizontal",length=200,mode="indeterminate",takefocus=True,maximum=100)
p.place(relx=0.43, rely=0.65, height=15, width=160)
p_Lab = Tk.Label(root,text='Processing..Hold On..')
p_Lab.place(relx=0.43, rely=0.68, height=50, width=160)
p.start()
p.update_idletasks()
def start_submit_thread():
global submit_thread
run_progressbar()
submit_thread = threading.Thread(target=go_ahead())
submit_thread.daemon = True
submit_thread.start()
root.after(20, check_submit_thread)
def check_submit_thread():
if submit_thread.is_alive():
p.update_idletasks()
root.after(20, check_submit_thread)
else:
p.update_idletasks()
p.stop()
p.destroy()
p_Lab.destroy()
root.update()
def justprint(root):
start_time = datetime.datetime.now().time().strftime('%H:%M:%S')
print ("Start", start_time)
start_submit_thread()
OkButton = Tk.Button(root, text = 'Perform Matches', height=5,width = 15,borderwidth=3,bg='grey',fg='black', command=lambda root=root:justprint(root))
OkButton.place(relx=0.45, rely=0.77, height=50, width=100)
OkButton2 = Tk.Label(root, text="(Once you start, it cannot be reverted back. Wait until processing is completed)")
OkButton2.place(relx=0.3, rely=0.88, height=20, width=460)
def main():
Tk.mainloop()
if __name__ == '__main__':
main()
Upvotes: 0
Views: 766
Reputation: 123463
Your code isn't working for two primary reason, the first being because it's accessing tkinter
from a thread and tkinter
doesn't support multi-threading. That can be fixed by removing everything in the go_ahead()
function except for the sleep()
call, and instead do the things removed in the check_submit_thread()
function—if necessary—which is repeatedly checking the status of the worker thread from the main one.
The other significant mistake I noticed was that the thread object was being created using:
threading.Thread(target=go_ahead())
rather than:
threading.Thread(target=go_ahead)
The problem with the former is that it calls go_ahead()
as the thread object is being created rather than when the thread object's start()
method is called.
In addition I made other relatively minor changes so the code adheres better to the PEP 8 - Style Guide for Python Code recommendations to improved its readability, plus actually be runnable using either Python 2 or 3.
from __future__ import print_function
import datetime
import sys
import threading
import time as T
try:
import Tkinter as tk
import tkFileDialog
import tkMessageBox
import ttk
except ModuleNotFoundError: # Python 3
import tkinter as tk
from tkinter import filedialog as tkFileDialog
import tkinter.messagebox as tkMessageBox
from tkinter import ttk
fname1=[]
fname2=[]
root = tk.Tk()
root.wm_title("Fuzzy Match Wizard")
root.resizable(False, False)
window_height = 600
window_width = 1000
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x_cordinate = int((screen_width/2) - (window_width/2))
y_cordinate = int((screen_height/2) - (window_height/2))
root.geometry("{}x{}+{}+{}".format(window_width, window_height, x_cordinate, y_cordinate))
root.configure(
# background='PaleGreen4',
relief='ridge', highlightcolor="black", takefocus="15", width="5")
def go_ahead():
""" This represents the fuzzy matching thread. """
# DON'T USE/ACCESS TKINTER IN THIS THREAD!
T.sleep(10)
def run_progressbar():
global p
global p_Lab
p = ttk.Progressbar(root, orient="horizontal", length=200, mode="indeterminate",
takefocus=True, maximum=100)
p.place(relx=0.43, rely=0.65, height=15, width=160)
p_Lab = tk.Label(root,text='Processing..Hold On..')
p_Lab.place(relx=0.43, rely=0.68, height=50, width=160)
p.start()
def start_submit_thread():
global submit_thread
submit_thread = threading.Thread(target=go_ahead)
submit_thread.daemon = True
submit_thread.start()
run_progressbar()
root.after(20, check_submit_thread)
def check_submit_thread():
if submit_thread.is_alive():
p.step()
root.after(20, check_submit_thread)
else:
p.stop()
p.destroy()
p_Lab.destroy()
stop_time = datetime.datetime.now().time().strftime('%H:%M:%S')
print("Stop", stop_time)
tkMessageBox.showinfo(title="Greetings", message="Fuzzy Match Completed")
def justprint(root):
start_time = datetime.datetime.now().time().strftime('%H:%M:%S')
print("Start", start_time)
start_submit_thread()
OkButton = tk.Button(root, text='Perform Matches', height=5, width=15, borderwidth=3,
bg='grey', fg='black', command=lambda root=root: justprint(root))
OkButton.place(relx=0.45, rely=0.77, height=50, width=100)
OkButton2 = tk.Label(root, text="(Once you start, it cannot be reverted back."
" Wait until processing is completed)")
OkButton2.place(relx=0.3, rely=0.88, height=20, width=460)
def main():
tk.mainloop()
if __name__ == '__main__':
main()
Upvotes: 2