Skip to content

Instantly share code, notes, and snippets.

@MattWoodhead
Created June 11, 2017 17:33
Show Gist options
  • Save MattWoodhead/c7c51cd2beaea33e1b8f5057f7a7d78a to your computer and use it in GitHub Desktop.
Save MattWoodhead/c7c51cd2beaea33e1b8f5057f7a7d78a to your computer and use it in GitHub Desktop.
tkinter progress bar example with threading
"""
An examnple of the use of threading to allow simultaneous operations in a
tkinter gui (which is locked to a single thread)
"""
import threading
import tkinter as tk
from tkinter import ttk
class Progress():
""" threaded progress bar for tkinter gui """
def __init__(self, parent, row, column, columnspan):
self.maximum = 100
self.interval = 10
self.progressbar = ttk.Progressbar(parent, orient=tk.HORIZONTAL,
mode="indeterminate",
maximum=self.maximum)
self.progressbar.grid(row=row, column=column,
columnspan=columnspan, sticky="we")
self.thread = threading.Thread()
self.thread.__init__(target=self.progressbar.start(self.interval),
args=())
self.thread.start()
def pb_stop(self):
""" stops the progress bar """
if not self.thread.isAlive():
VALUE = self.progressbar["value"]
self.progressbar.stop()
self.progressbar["value"] = VALUE
def pb_start(self):
""" starts the progress bar """
if not self.thread.isAlive():
VALUE = self.progressbar["value"]
self.progressbar.configure(mode="indeterminate",
maximum=self.maximum,
value=VALUE)
self.progressbar.start(self.interval)
def pb_clear(self):
""" stops the progress bar """
if not self.thread.isAlive():
self.progressbar.stop()
self.progressbar.configure(mode="determinate", value=0)
def pb_complete(self):
""" stops the progress bar and fills it """
if not self.thread.isAlive():
self.progressbar.stop()
self.progressbar.configure(mode="determinate",
maximum=self.maximum,
value=self.maximum)
def printmsg():
""" prints a message in a seperate thread to tkinter """
print("proof a seperate thread is running")
class AppGUI(tk.Frame):
""" class to define tkinter GUI"""
def __init__(self, parent,):
tk.Frame.__init__(self, master=parent)
prog_bar = Progress(parent, row=0, column=0, columnspan=2)
# Button 1
start_button = ttk.Button(parent, text="start",
command=prog_bar.pb_start)
start_button.grid(row=1, column=0)
# Button 2
stop_button = ttk.Button(parent, text="stop",
command=prog_bar.pb_stop)
stop_button.grid(row=1, column=1)
# Button 3
complete_button = ttk.Button(parent, text="complete",
command=prog_bar.pb_complete)
complete_button.grid(row=2, column=0)
# Button 4
clear_button = ttk.Button(parent, text="clear",
command=prog_bar.pb_clear)
clear_button.grid(row=2, column=1)
# Button 5
test_print_button = ttk.Button(parent, text="thread test",
command=printmsg)
test_print_button.grid(row=3, column=0, columnspan=2, sticky="we")
ROOT = tk.Tk()
APP = AppGUI(ROOT)
ROOT.mainloop()
@TheLizzard
Copy link

First of all this:

self.thread = threading.Thread()
self.thread.__init__(target=self.progressbar.start(self.interval),
                             args=())

is very unpythonic. Also you aren't calling self.progressbar.start in the new thread. You are calling it then setting target to what ever the function returns (probably None). Also why do you have args=() you can just remove it.

@TheLizzard
Copy link

Also all event/commands (like command=printmsg) run the the tkinter thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment