Reputation: 678
I want to use Tkinter to interact with another thread. The output (assuming the user clicks the button after two seconds) should be:
Steve
Steve
Joline
Joline
Joline
Where am I going wrong?
from Tkinter import *
import time
import threading
from threading import Thread
def changeName():
person = "Joline"
def controls():
root = Tk()
button = Button(text="Change Name", command=changeName)
button.pack(side=LEFT)
root.mainloop()
def work():
person = "Steve"
for _ in range(5):
print("hello " + person)
time.sleep(1)
Thread(target = controls).start()
Thread(target = work).start()
Upvotes: 0
Views: 377
Reputation: 678
I had forgotten to make the "person" variable global. Here is what I should have done to get the desired result:
from Tkinter import *
import time
import threading
from threading import Thread
person = ""
def changeName():
global person
person = "Sonia"
def controls():
root = Tk()
button = Button(text="Change Name", command=changeName)
button.pack(side=LEFT)
root.mainloop()
def work():
for _ in range(10):
print("hello " + person)
time.sleep(1)
Thread(target = controls).start()
Thread(target = work).start()
Upvotes: 0
Reputation: 11615
Edit: Your name
variables are never changed because they are local to the respective functions they are in. This is a bad approach even if it does work. Tkinter is already one giant thread loop (what do you think mainloop
is doing, it's looping checking for events in the queue to process) you shouldn't be putting it inside another loop and we can use built-in methods to achieve this.
Just for kicks I imported string and random to create random strings so you could see it working.
The changeName
function could use sleep but we already have tkinter imported and it already has built-in functionality / event queue so why not use it...
I just added the name as an attribute to the Tk class rather than having to worry about globals, locals, etc.
import tkinter as tk, string, random
root = tk.Tk()
root.name = "a name"
def changeName(shouldRun=False):
if not shouldRun:
root.after(2000, changeName, True)
else:
root.name = "".join([random.choice(string.ascii_letters) for _ in range(10)])
def printName():
print(root.name)
root.after(1000, printName)
btn = tk.Button(root, text="Change Name", command=changeName)
btn.pack()
printName()
root.mainloop()
Upvotes: 1