Can't type text into tkinter entry widget (python)
I'm using tkinter to get a file path to open and then ask the user two questions, name via a text entry widget and course via some radiobuttons. The code for the radio buttons I got from the answer to this thread and it worked great: How do I display a dialog that asks the user multi-choice question using tkInter? Then I decided to add the Entry widget to get the answer to the name question and have been struggling. I've got it working, but with bugs:
- The text entry field comes pre-populated and when clicked it clears (it's meant to do this) but the cursor doesn't appear and I can't enter new text in the entry. If I click off the tkinter window and then back onto it the cursor appears and I can enter text as intended
- The top radio button appears pre-selected, except it isn't. The validate function says no radio button is selected. I can select another option and it works, but I can't select the first option, even if I click off the first option and then back on to it. EDIT: This problem was caused by my validate function, which discarded 0 values i.e. the top radio button. Thanks @acw1668 for the clue to solve this one. I've now set the starting value to -1 (so nothing is selected) and the validate function checks for -1
I can't figure out where to go from here. I've tried using e1.focus()
but it made no difference. I've tried running the questions window before the fileopen dialog but that really confused it. I've tried commenting out the clear entry function in case that was causing the problem but the behaviour was basically the same. EDIT: I'm using Spyder from Anaconda 3 as my IDE, I'm wondering if this is causing problem 1 as @acw1668 couldn't replicate it.
Here is my code:
root=tk.Tk()
csvfp=tk.filedialog.askopenfilename()
SName, ProgSel=ask_multiple_choice_question(root, LPrograms)
def ask_multiple_choice_question(root, options):
#https://stackoverflow.com/questions/42581016/how-do-i-display-a-dialog-that-asks-the-user-multi-choice-question-using-tkinter
#Define a function to clear the contents of the textbox when it is clicked
def click(event):
e1.configure(state=tk.NORMAL)
e1.delete(0,tk.END)
e1.unbind('<Button-1>',clicked)
#checks entries are valid when submit button is clicked, then closes window
def validate():
if v.get() == 0 or v2.get() == "" or v2.get()==starttext:
return None
root.destroy()
frame1=Frame(root)
frame1.pack(padx=20,pady=10)
frame2=Frame(root)
frame2.pack()
frame3=Frame(root)
frame3.pack(pady=10)
Label(frame1, text="Student name?").pack()
v2=tk.StringVar()
e1 = Entry(frame1, width=30, textvariable=v2)
starttext="Surname, Firstname (ID)"
e1.insert(0, starttext)
e1.pack()
#bind e1 with mouse button to clear contents on click
clicked=e1.bind('<Button-1>',click)
Label(frame2, text="Program?").pack()
v = IntVar()
for i, option in enumerate(options):
Radiobutton(frame2, text=option, variable=v, value=i).pack(anchor="w")
Button(frame3, text="Submit", command=validate).pack()
root.mainloop()
return v2.get(), options[v.get()]
Thanks for any clues!
For issue #1, you need to show the file dialog after the main window is ready and visible. You can call root.wait_visibility()
after root = tk.Tk()
:
...
root = tk.Tk()
root.wait_visibility()
...
For issue #2, since the value
option of the first radio button is 0 and the initial value of its tkinter variable v
is default 0, so the first radio button will be selected. Set the initial value of v
to -1 will fix it:
...
def validate():
# check -1 instead of 0
if v.get() == -1 or v2.get() == "" or v2.get() == starttext:
return None
root.destroy()
...
v = tk.IntVar(value=-1)
...