how can i control each button individually in tkinter - python-3.x

How can i control each button individually in tkinter?
Here is my code:
from tkinter import *
class Minesweeper:
def __init__(self,action):
L=[]
for i in range(15):
for j in range(15):
self.action = Button(win, text = " h ",command = self.clickMe)
self.action.grid(column = i, row = j)
def clickMe(self):
self.action.configure(foreground = "red")
def main():
global win
win = Tk()
win.title('Minesweeper')
game = Minesweeper(win)
win.mainloop()
main()

Better way is a binding some event to button:
from tkinter import *
class Minesweeper:
def __init__(self, action):
L=[]
for i in range(15):
for j in range(15):
self.action = Button(win, text="h")
# bind to button function 'clickMe' that runs while <Button-1> clicked on it
self.action.bind("<Button-1>", self.clickMe)
self.action.grid(column=i, row=j)
def clickMe(self, event):
"""changes the 'fg' color of the events widget"""
event.widget.configure(foreground="red")
def main():
global win
win = Tk()
win.title('Minesweeper')
game = Minesweeper(win)
win.mainloop()
main()

Related

Drag Drop List in Tkinter

from tkinter import *
import tkinter as tk
root = tk.Tk()
def add_many_songs():
# Loop thru to fill list box
for song in range(11):
playlist_box.insert(END, song)
playlist_box =tk.Listbox(root,bg="black", fg="green", width=60, selectbackground="green", selectforeground='black',font = 20)
playlist_box.grid(row=0, column=0)
add_many_songs()
class DragDropListbox(tk.Listbox):
""" A Tkinter listbox with drag'n'drop reordering of entries. """
def __init__(self, master, **kw):
kw['selectmode'] = tk.SINGLE
tk.Listbox.__init__(self, master, kw)
self.bind('<Button-1>', self.setCurrent)
self.bind('<B1-Motion>', self.shiftSelection)
self.curIndex = None
def setCurrent(self, event):
self.curIndex = self.nearest(event.y)
def shiftSelection(self, event):
i = self.nearest(event.y)
if i < self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i+1, x)
self.curIndex = i
elif i > self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i-1, x)
self.curIndex = i
##I found this code that does drag and drop features within tkinter list. I got it to work with the example code. However, I am not able to get it to work within the attached code. I am still learning Python.
You should use the class DragDropListbox instead of tk.Listbox when creating playlist_box:
import tkinter as tk
def add_many_songs():
# Loop thru to fill list box
for song in range(11):
playlist_box.insert(tk.END, song)
class DragDropListbox(tk.Listbox):
""" A Tkinter listbox with drag'n'drop reordering of entries. """
def __init__(self, master, **kw):
kw['selectmode'] = tk.SINGLE
tk.Listbox.__init__(self, master, kw)
self.bind('<Button-1>', self.setCurrent)
self.bind('<B1-Motion>', self.shiftSelection)
self.curIndex = None
def setCurrent(self, event):
self.curIndex = self.nearest(event.y)
def shiftSelection(self, event):
i = self.nearest(event.y)
if i < self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i+1, x)
self.curIndex = i
elif i > self.curIndex:
x = self.get(i)
self.delete(i)
self.insert(i-1, x)
self.curIndex = i
root = tk.Tk()
playlist_box = DragDropListbox(root,bg="black", fg="green", width=60, selectbackground="green", selectforeground='black',font = 20)
playlist_box.grid(row=0, column=0)
add_many_songs()
root.mainloop()
Note that it is not recommended to import tkinter like below:
from tkinter import *
import tkinter as tk
Just use import tkinter as tk.

Tkinter buttons not changing back to the correct color after state changing to active

I am making this PDF tool, and I want the buttons to be disabled until a file or files are successfully imported. This is what the app looks like at the launch:
Right after running the callback for the import files button, the active state looks like this:
I want the colors of the buttons to turn maroon instead of the original grey. They only turn back to maroon once you hover the mouse over them. Any thoughts for how to fix this? Here is the callback for the import button:
def import_callback():
no_files_selected = False
global files
files = []
try:
ocr_button['state'] = DISABLED
merge_button['state'] = DISABLED
status_label.pack_forget()
frame.pack_forget()
files = filedialog.askopenfilenames()
for f in files:
name, extension = os.path.splitext(f)
if extension != '.pdf':
raise
if not files:
no_files_selected = True
raise
if frame.winfo_children():
for label in frame.winfo_children():
label.destroy()
make_import_file_labels(files)
frame.pack()
ocr_button['state'] = ACTIVE
merge_button['state'] = ACTIVE
except:
if no_files_selected:
status_label.config(text='No files selected.', fg='blue')
else:
status_label.config(text='Error: One or more files is not a PDF.', fg='red')
status_label.pack(expand='yes')
import_button = Button(root, text='Import Files', width=scaled(20), bg='#5D1725', bd=0, fg='white', relief='groove',
command=import_callback)
import_button.pack(pady=scaled(50))
I know this was asked quite a while ago, so probably already solved for the user. But since I had the exact same problem and do not see the "simplest" answer here, I thought I would post:
Just change the state from "active" to "normal"
ocr_button['state'] = NORMAL
merge_button['state'] = NORMAL
I hope this helps future users!
As I understand you right you want something like:
...
ocr_button['state'] = DISABLED
ocr_button['background'] = '#*disabled background*'
ocr_button.bind('<Enter>', lambda e:ocr_button.configure(background='#...'))
ocr_button.bind('<Leave>', lambda e:ocr_button.configure(background='#...'))
merge_button['state'] = DISABLED
merge_button['background'] = '#*disabled background*'
merge_button.bind('<Enter>', lambda e:ocr_button.configure(background='#...'))
merge_button.bind('<Leave>', lambda e:ocr_button.configure(background='#...'))
...
...
ocr_button['state'] = ACTIVE
ocr_button['background'] = '#*active background*'
ocr_button.unbind('<Enter>')
ocr_button.unbind('<Leave>')
merge_button['state'] = ACTIVE
merge_button['background'] = '#*active background*'
merge_button.unbind('<Enter>')
merge_button.unbind('<Leave>')
...
If there are any errors, since I wrote it out of my mind or something isnt clear, let me know.
Update
the following code reproduces the behavior as you stated. The reason why this happens is how tkinter designed the standart behavior. You will have a better understanding of it if you consider style of ttk widgets. So I would recommand to dont use the automatically design by state rather write a few lines of code to configure your buttons how you like, add and delete the commands and change the background how you like. If you dont want to write this few lines you would be forced to use ttk.Button and map a behavior you do like
import tkinter as tk
root = tk.Tk()
def func_b1():
print('func of b1 is running')
def disable_b1():
b1.configure(bg='grey', command='')
def activate_b1():
b1.configure(bg='red', command=func_b1)
b1 = tk.Button(root,text='B1', bg='red',command=func_b1)
b2 = tk.Button(root,text='disable', command=disable_b1)
b3 = tk.Button(root,text='activate',command=activate_b1)
b1.pack()
b2.pack()
b3.pack()
root.mainloop()
I've wrote this simple app that I think could help all to reproduce the problem.
Notice that the state of the button when you click is Active.
#!/usr/bin/python3
import sys
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class Main(ttk.Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__()
self.parent = parent
self.init_ui()
def cols_configure(self, w):
w.columnconfigure(0, weight=0, minsize=100)
w.columnconfigure(1, weight=0)
w.rowconfigure(0, weight=0, minsize=50)
w.rowconfigure(1, weight=0,)
def get_init_ui(self, container):
w = ttk.Frame(container, padding=5)
self.cols_configure(w)
w.grid(row=0, column=0, sticky=tk.N+tk.W+tk.S+tk.E)
return w
def init_ui(self):
w = self.get_init_ui(self.parent)
r = 0
c = 0
b = ttk.LabelFrame(self.parent, text="", relief=tk.GROOVE, padding=5)
self.btn_import = tk.Button(b,
text="Import Files",
underline=1,
command = self.on_import,
bg='#5D1725',
bd=0,
fg='white')
self.btn_import.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
self.parent.bind("<Alt-i>", self.switch)
r +=1
self.btn_ocr = tk.Button(b,
text="OCR FIles",
underline=0,
command = self.on_ocr,
bg='#5D1725',
bd=0,
fg='white')
self.btn_ocr["state"] = tk.DISABLED
self.btn_ocr.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
r +=1
self.btn_merge = tk.Button(b,
text="Merge Files",
underline=0,
command = self.on_merge,
bg='#5D1725',
bd=0,
fg='white')
self.btn_merge["state"] = tk.DISABLED
self.btn_merge.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
r +=1
self.btn_reset = tk.Button(b,
text="Reset",
underline=0,
command = self.switch,
bg='#5D1725',
bd=0,
fg='white')
self.btn_reset.grid(row=r, column=c, sticky=tk.N+tk.W+tk.E,padx=5, pady=5)
b.grid(row=0, column=1, sticky=tk.N+tk.W+tk.S+tk.E)
def on_import(self, evt=None):
self.switch()
#simulate some import
self.after(5000, self.switch())
def switch(self,):
state = self.btn_import["state"]
if state == tk.ACTIVE:
self.btn_import["state"] = tk.DISABLED
self.btn_ocr["state"] = tk.NORMAL
self.btn_merge["state"] = tk.NORMAL
else:
self.btn_import["state"] = tk.NORMAL
self.btn_ocr["state"] = tk.DISABLED
self.btn_merge["state"] = tk.DISABLED
def on_ocr(self, evt=None):
state = self.btn_ocr["state"]
print ("ocr button state is {0}".format(state))
def on_merge(self, evt=None):
state = self.btn_merge["state"]
print ("merge button state is {0}".format(state))
def on_close(self, evt=None):
self.parent.on_exit()
class App(tk.Tk):
"""Main Application start here"""
def __init__(self, *args, **kwargs):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_style()
self.set_title(kwargs['title'])
Main(self, *args, **kwargs)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("clam")
def set_title(self, title):
s = "{0}".format('Simple App')
self.title(s)
def on_exit(self):
"""Close all"""
if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
self.destroy()
def main():
args = []
for i in sys.argv:
args.append(i)
kwargs = {"style":"clam", "title":"Simple App",}
app = App(*args, **kwargs)
app.mainloop()
if __name__ == '__main__':
main()

python 3+ with tkinter: modal window not appearing

I'm new to python. I'm trying to set up a GUI with a main window and a modal window to receive the database credentials. The main window has to be in the background when the modal window appears and the user should not interact with it. Actually the application should terminate in case the user fails to provide a valid username and password. I'm presenting part of the code here. What I get is the main window (the modal window does not appear at all) and I can't do anything but shut the program down - not directly; only through visual studio.
'''
import tkinter as tk
class login:
def checkDbCredentials(self, user, password):
if (len(user)<4 or len(password)<4):
return 0
return 1
def ok(self):
us = self.user.get()
pw = self.password.get()
if self.checkDbCredentials(us, pw)==0:
tk.messagebox.showinfo("Error", "Username and Password do not match")
sys.exit(0)
self.dic['user']=us
self.dic['pass']=pw
self.win2.destroy()
def cancel(self, event=None):
self.parent.focus_set()
self.destroy()
def widgets(self):
x = self.win2.winfo_screenwidth()
y = self.win2.winfo_screenheight()
xx = int((x-270)/2)
yy = int((y-85)/2)
geo = "270x85+" + str(xx) + "+" + str(yy)
self.win2.geometry(newGeometry=geo)
self.tempLab= tk.Label(self.win2, text="Username:", pady=5)
self.tempLab1 = tk.Label(self.win2, text="Password:")
self.iuser = tk.Entry(self.win2, textvariable = self.user, width=30)
self.ipass = tk.Entry(self.win2, textvariable = self.password, width=30, show="*")
self.tempLab.grid(column=0, row=0)
self.tempLab1.grid(column=0, row=1)
self.iuser.grid(column=1, row=0)
self.ipass.grid(column=1, row=1)
self.bt = tk.Button(self.win2, text="Submit", command=lambda: self.ok())
self.bt.grid(column=0, row=2, columnspan=2, pady=5)
self.win2.bind("<Return>", self.ok)
self.win2.bind("<Escape>", self.cancel)
def __init__(self, dic, parent):
self.win2 = tk.Toplevel(parent)
self.parent=parent
self.dic = dic
self.user = tk.StringVar()
self.password = tk.StringVar()
self.win2.overrideredirect(1)
self.widgets()
self.win2.transient(parent)
self.win2.grab_set()
self.win2.protocol("WM_DELETE_WINDOW", self.cancel)
self.parent.wait_window(self.win2)
And the main class code is the following:
import tkinter as tk
from tkinter import ttk, X, Y, BOTH
from tkinter import messagebox
import sys
import login
class mainWindow:
def connect(bt, fr):
notImplementedYet()
def notImplementedYet():
msg = tk.messagebox
msg.showinfo("Warning", "Not Implemented yet!")
btX = 20
btY = 5
btSunken = '#aec2c2' # sunken button color
btRaised = '#85adad' # normal button color
rw = 0 # starting row for buttons
cl = 0 # starting column
dbCredentials = {"user":"", "pass":""}
win = tk.Tk()
win.title("Title")
win.geometry(newGeometry="1366x700+00+00")
win.iconbitmap(bitmap="bitmap.ico")
fr1 = tk.Frame(win, width=1366, height=50, background='beige')
fr1.grid(column=cl, row=rw, rowspan=5)
fr2 = tk.Frame(win)
fr2.grid(column=0, row=1)
lb2 = tk.Label(fr2, text="frame 2", background=btRaised)
btConnect = tk.Button(fr1, text="Connect", background = btRaised ,command=lambda: connect(btConnect, fr1), width=btX, height=btY)
btConnect.grid(column=0, row=0)
log = login.login(dbCredentials, win)
win.wait_window(log.win2)
print(dbCredentials)
win.mainloop()
win = mainWindow()
The question is why is the modal window not appearing? I've tried placing the 'wait_window' in the other class as well but it's still not working.

Tkinter create buttons from list each with its own function

I want to create buttons from a list and assign each button a function based on the list item. I tried below and the button doesn't respond to a click. I see solutions where a lambda function is used to pass a parameter to a function but I would like separate functions. Using Python 3.5 in Anaconda
import tkinter as tk
def North():
print('slected North')
def South():
print('slected South')
def East():
print('slected East')
def West():
print('slected West')
lst = ['North','South','East','West']
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text = Direction, command = Direction)
butName.grid(row = 1, column = col)
win.mainloop()
Your list contains strings; it needs to contain functions
lst = [North,South,East,West]
Faster and better:
import tkinter as tk
def onbutton_click(label):
print('selected ', label)
lst = ['North','South','East','West']
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text=Direction, command=lambda e=Direction: onbutton_click(e))
butName.grid(row=0, column=col)
win.mainloop()
or your way:
import tkinter as tk
def North():
print('slected North')
def South():
print('slected South')
def East():
print('slected East')
def West():
print('slected West')
lst = [North, South,East, West]
win = tk.Tk()
win.title = 'Compass'
for col,Direction in enumerate(lst):
butName = tk.Button(win, text=Direction.__name__, command=Direction)
butName.grid(row=0, column=col)
win.mainloop()
I also set the row as 0 cause there is no need to be 1.

Updating a tk ProgressBar from a multiprocess.proccess in python3

I have successfully created a threading example of a thread which can update a Progressbar as it goes. However doing the same thing with multiprocessing has so far eluded me.
I'm beginning to wonder if it is possible to use tkinter in this way. Has anyone done this?
I am running on OS X 10.7. I know from looking around that different OS's may behave very differently, especially with multiprocessing and tkinter.
I have tried a producer which talks directly to the widget, through both namespaces and event.wait, and event.set. I have done the same thing with a producer talking to a consumer which is either a method or function which talks to the widget. All of these things successfully run, but do not update the widget visually. Although I have done a get() on the IntVar the widget is bound to and seen it change, both when using widget.step() and/or widget.set(). I have even tried running a separate tk() instance inside the sub process. Nothing updates the Progressbar.
Here is one of the simpler versions. The sub process is a method on an object that is a wrapper for the Progressbar widget. The tk GUI runs as the main process. I also find it a little odd that the widget does not get destroyed at the end of the loop, which is probably a clue I'm not understanding the implications of.
import multiprocessing
from tkinter import *
from tkinter import ttk
import time
root = Tk()
class main_window:
def __init__(self):
self.dialog_count = 0
self.parent = root
self.parent.title('multiprocessing progess bar')
frame = ttk.Labelframe(self.parent)
frame.pack(pady=10, padx=10)
btn = ttk.Button(frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=1, pady=10)
btn = ttk.Button(frame, text="progress_bar")
btn.bind("<Button-1>", self.pbar)
btn.grid(row=0, column=2, pady=10)
self.parent.mainloop()
def pbar(self, event):
name="producer %d" % self.dialog_count
self.dialog_count += 1
pbar = pbar_dialog(self.parent, title=name)
event = multiprocessing.Event()
p = multiprocessing.Process(target=pbar.consumer, args=(None, event))
p.start()
def cancel(self, event):
self.parent.destroy()
class pbar_dialog:
toplevel=None
pbar_count = 0
def __init__(self, parent, ns=None, event=None, title=None, max=100):
self.ns = ns
self.pbar_value = IntVar()
self.max = max
pbar_dialog.pbar_count += 1
self.pbar_value.set(0)
if not pbar_dialog.toplevel:
pbar_dialog.toplevel= Toplevel(parent)
self.frame = ttk.Labelframe(pbar_dialog.toplevel, text=title)
#self.frame.pack()
self.pbar = ttk.Progressbar(self.frame, length=300, variable=self.pbar_value)
self.pbar.grid(row=0, column=1, columnspan=2, padx=5, pady=5)
btn = ttk.Button(self.frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=3, pady=10)
self.frame.pack()
def set(self,value):
self.pbar_value.set(value)
def step(self,increment=1):
self.pbar.step(increment)
print ("Current", self.pbar_value.get())
def cancel(self, event):
self.destroy()
def destroy(self):
self.frame.destroy()
pbar_dialog.pbar_count -= 1
if pbar_dialog.pbar_count == 0:
pbar_dialog.toplevel.destroy()
def consumer(self, ns, event):
for i in range(21):
#event.wait(2)
self.step(5)
#self.set(i)
print("Consumer", i)
self.destroy()
if __name__ == '__main__':
main_window()
For contrast, here is the threading version which works perfectly.
import threading
from tkinter import *
from tkinter import ttk
import time
root = Tk()
class main_window:
def __init__(self):
self.dialog_count = 0
self.parent = root
self.parent.title('multiprocessing progess bar')
frame = ttk.Labelframe(self.parent)
frame.pack(pady=10, padx=10)
btn = ttk.Button(frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=1, pady=10)
btn = ttk.Button(frame, text="progress_bar")
btn.bind("<Button-1>", self.pbar)
btn.grid(row=0, column=2, pady=10)
self.parent.mainloop()
def producer(self, pbar):
i=0
while i < 101:
time.sleep(1)
pbar.step(1)
i += 1
pbar.destroy()
def pbar(self, event):
name="producer %d" % self.dialog_count
self.dialog_count += 1
pbar = pbar_dialog(self.parent, title=name)
p = threading.Thread(name=name, target=self.producer, args=(pbar,))
p.start()
#p.join()
def cancel(self, event):
self.parent.destroy()
class pbar_dialog:
toplevel=None
pbar_count = 0
def __init__(self, parent, ns=None, event=None, title=None, max=100):
self.ns = ns
self.pbar_value = IntVar()
self.title = title
self.max = max
pbar_dialog.pbar_count += 1
if not pbar_dialog.toplevel:
pbar_dialog.toplevel= Toplevel(parent)
self.frame = ttk.Labelframe(pbar_dialog.toplevel, text=title)
#self.frame.pack()
self.pbar = ttk.Progressbar(self.frame, length=300, variable=self.pbar_value)
self.pbar.grid(row=0, column=1, columnspan=2, padx=5, pady=5)
btn = ttk.Button(self.frame, text="Cancel")
btn.bind("<Button-1>", self.cancel)
btn.grid(row=0, column=3, pady=10)
self.frame.pack()
self.set(0)
def set(self,value):
self.pbar_value.set(value)
def step(self,increment=1):
self.pbar.step(increment)
def cancel(self, event):
self.destroy()
def destroy(self):
self.frame.destroy()
pbar_dialog.pbar_count -= 1
if pbar_dialog.pbar_count == 0:
pbar_dialog.toplevel.destroy()
pbar_dialog.toplevel = None
def automatic(self, ns, event):
for i in range(1,100):
self.step()
if __name__ == '__main__':
main_window()
Doing something similar, I ended up having to use a combination of threads and processes - the GUI front end had two threads: one for tkinter, and one reading from a multiprocessing.Queue and calling gui.update() - then the back-end processes would write updates into that Queue
This might be a strange approach, but it works for me. Copy and paste this code to a file and run it to see the result. It's ready to run.
I don't have the patience to explain my code right now, I might edit it another day.
Oh, and this is in Python 2.7 I started programming two months ago, so I have not idea if the difference is relevant.
# -*- coding: utf-8 -*-
# threadsandprocesses.py
# Importing modules
import time
import threading
import multiprocessing
import Tkinter as tki
import ttk
class Master(object):
def __init__(self):
self.mainw = tki.Tk()
self.mainw.protocol("WM_DELETE_WINDOW", self.myclose)
self.mainw.title("Progressbar")
self.mainw.geometry('300x100+300+300')
self.main = tki.Frame(self.mainw)
self.RunButton = ttk.Button(self.main, text='Run',
command=self.dostuff)
self.EntryBox = ttk.Entry(self.main)
self.EntryBox.insert(0, "Enter a number")
self.progress = ttk.Progressbar(self.main,
mode='determinate', value=0)
self.main.pack(fill=tki.BOTH, expand=tki.YES)
self.progress.pack(expand=tki.YES)
self.EntryBox.pack(expand=tki.YES)
self.RunButton.pack()
print "The Master was created"
def dostuff(self):
print "The Master does no work himself"
data = range(int(self.EntryBox.get()))
S = Slave(self, data)
print "The Master created a Slave to do his stuff"
print "The Slave gets told to start his work"
S.start()
def myclose(self):
self.mainw.destroy()
return
def nextstep(self):
print "Good job, Slave, I see the result is"
print Master.results.get()
class Slave(threading.Thread):
def __init__(self, guest, data):
print "This is the Slave."
print "Nowdays, Work is outsourced!"
self.data = data
self.guest = guest
threading.Thread.__init__(self)
def run(self):
print "The Slave is outsourcing his work to Calcualte inc."
time.sleep(1)
Outsourcing = Calculate()
Results = Outsourcing.run(self.guest, self.data)
return Results
# unwrapping outside a class
def calc(arg, **kwarg):
return Calculate.calculate(*arg, **kwarg)
class Calculate(object):
def run(self, guest, data):
print"This is Calculate inc. ... how can I help you?"
time.sleep(1)
maximum = int(guest.EntryBox.get())
guest.progress.configure(maximum=maximum, value=0)
manager = multiprocessing.Manager()
queue = manager.Queue()
lock = manager.Lock()
print "Things are setup and good to go"
# Counting the number of available CPUs in System
pool_size = multiprocessing.cpu_count()
print "Your system has %d CPUs" % (pool_size)
# Creating a pool of processes with the maximal number of CPUs possible
pool = multiprocessing.Pool(processes=pool_size)
Master.results = pool.map_async(calc, (zip([self]*len(data), [lock]*len(data),
[queue]*len(data), data)))
for job in range(1, maximum+1):
queue.get() # this is an abuse I think, but works for me
guest.progress.configure(value=job)
# Properly close and end all processes, once we're done
pool.close()
pool.join()
print "All done"
guest.nextstep()
return
def calculate(self, lock, queue, indata):
lock.acquire()
print 'Reading values and starting work'
lock.release()
time.sleep(3) # some work
results = indata # The works results
lock.acquire()
print 'Done'
lock.release()
queue.put("Finished!")
return results
if __name__ == '__main__':
TheMaster = Master()
TheMaster.mainw.mainloop()

Resources