Reputation: 754
My goal is to be able to pass string variables to two different entries for user validation and return the user modified values. The code works fine if it is executed a single time; however, when looped, it only performs correctly during the first iteration of the loop. During subsequent iterations the string variables for the entries are blank.
I have experimented with update_idletasks()
and time-sleep without luck. I am running Python 2.4 on Windows XP.
# -*- coding: cp1252 -*-
import Tkinter
def retrieve_text():
app_win.quit()
for item in range(3):
numero_dossier = item+1
version_dossier = item+2
app_win = Tkinter.Tk()
l = Tkinter.Label(app_win, text="Veuillez valider les informations suivantes et les corriger au besoin :")
l.grid(row=0, column=0, columnspan=2)
l.pack()
v1 = Tkinter.StringVar()
v1.set(numero_dossier)
l1 = Tkinter.Label(app_win, text="Numéro de dossier:", anchor='w', justify='left')
e1 = Tkinter.Entry(app_win, textvariable=v1)
l1.pack()
e1.pack()
v2 = Tkinter.StringVar()
v2.set(version_dossier)
l2 = Tkinter.Label(app_win, text="Version du dossier:", anchor='w', justify='left')
e2 = Tkinter.Entry(app_win, textvariable=v2)
l2.pack()
e2.pack()
app_button = Tkinter.Button(app_win,text="OK",command=retrieve_text)
app_button.pack()
app_win.mainloop()
app_win.withdraw()
numero_dossier = e1.get().strip()
version_dossier = e2.get().strip()
print numero_dossier, version_dossier
Upvotes: 1
Views: 3681
Reputation: 754
Thanks to Bryan Oakley and mmgp, I was able to come up with the following code that does what I need, even though I am breaking the mainloop rule as it gets called during each iteration of the loop. All comments are welcome. Thanks again!
# -*- coding: cp1252 -*-
import Tkinter
root = Tkinter.Tk()
def retrieve_and_update_text():
#global CURR_D
dossier = e1.get().strip()
version = e2.get().strip().upper()
print dossier, version
root.quit()
for item in range(3):
dossier = item+1
version = item+2
l = Tkinter.Label(root, text=u"Veuillez valider les informations suivantes et les corriger au besoin :")
l.grid(row=0, column=0, columnspan=2)
v1 = Tkinter.StringVar()
l1 = Tkinter.Label(root, text=u"Dossier :", anchor='w', justify='left')
e1 = Tkinter.Entry(root, textvariable=v1)
l1.grid(row=1)
e1.grid(row=1, column=1)
v2 = Tkinter.StringVar()
l2 = Tkinter.Label(root, text=u"Version :", anchor='w', justify='left')
e2 = Tkinter.Entry(root, textvariable=v2)
l2.grid(row=2)
e2.grid(row=2, column=1)
app_button = Tkinter.Button(root, text=u"OK", command=retrieve_and_update_text)
app_button.grid(row=3)
v1.set(dossier)
v2.set(version)
root.mainloop()
if item == range(3)[-1]: # if last item
root.withdraw()
Upvotes: -1
Reputation: 19221
There is no rationale in the question on why the widgets are being constructed multiple times, so I will take that as a mistake. Also, the name app_win
for an Tkinter.Tk
instance might be fooling you. Instantiating Tkinter.Tk
starts a tcl interpreter, and then loads tk which as a "bonus" gives you a window.
The more sensible approach is creating the widgets only once, and then doing the multiple validations you are after. Here is your code adjusted for this:
import Tkinter
NUM_D = range(3)
VER_D = range(3)
CURR_D = 0
def retrieve_and_update_text():
global CURR_D
num_d = e1.get().strip()
ver_d = e2.get().strip()
print num_d, ver_d
CURR_D = (CURR_D + 1) % 3
v1.set(NUM_D[CURR_D] + 1)
v2.set(VER_D[CURR_D] + 2)
root = Tkinter.Tk()
l = Tkinter.Label(root, text=u"Label")
l.grid(row=0, column=0, columnspan=2)
v1 = Tkinter.StringVar()
l1 = Tkinter.Label(root, text=u"Num", anchor='w', justify='left')
e1 = Tkinter.Entry(root, textvariable=v1)
l1.grid(row=1)
e1.grid(row=1, column=1)
v2 = Tkinter.StringVar()
l2 = Tkinter.Label(root, text=u"Ver", anchor='w', justify='left')
e2 = Tkinter.Entry(root, textvariable=v2)
l2.grid(row=2)
e2.grid(row=2, column=1)
app_button = Tkinter.Button(root, text=u"OK", command=retrieve_and_update_text)
app_button.grid(row=3)
v1.set(NUM_D[CURR_D] + 1)
v2.set(VER_D[CURR_D] + 2)
root.mainloop()
Upvotes: 1
Reputation: 385980
This is fundamentally broken:
for item in range(3):
...
app_win = Tkinter.Tk()
Tkinter is simply not designed to work this way. Your program should only ever create a single instance of the class Tk
, and you should call mainloop
exactly once.
Upvotes: 2