OptionMenu won't show the first option when clicked (Tkinter)
Asked Answered
M

3

5

I added a OptionMenu widget to my code, and assigned a list as it's options. This is how it is:

z = StringVar()   
z.set(userList[0])    
usersOption = OptionMenu(frame1, z, *userList)#, command=changeUser)
usersOption.pack(side=RIGHT, padx=3)

Now, I reckon it would show all the options in said list. As so:

Option 1 \/ <-- the box with the selected option
Option 1 }\__the options that show on click
Option 2 }/

but it actually only shows the second option, and when I choose it there is, basically, no way back, if I click the box again it keeps only showing option 2 and I can't change it even with the up and down keys. I tried looking for solutions, but I got nowhere, so I'm starting to think it is the default operating way of the widget, but I found nothing to show me how to solve it in the documentation I read.
P.S.: I'm using Python 3.3

Mancini answered 13/5, 2013 at 2:38 Comment(2)
is z an instance of a Tkinter StringVar? Are you absolutely certain that userlist has the value you think it has?Elwandaelwee
yes, it is and yes, it does. The list is created from a txt file's lines without the line breakers '\n' (for that I use .strip()). This text file has, currently, two lines: "User 1" and "User 2". And it is set to userList[0]. (I'll edit the text to add this)Mancini
W
8

I had the same problem and it was driving me mad, so i looked in the source. I think the issue is that the 3rd constructor argument is the default value. If you don't specify it before *userList, it looks like it takes the first item as the default value. A real fix would be something like:

z = StringVar()   
z.set(userList[0])    
usersOption = OptionMenu(frame1, z, userList[0] ,*userList)#, command=changeUser)
usersOption.pack(side=RIGHT, padx=3)
Win answered 22/10, 2013 at 22:6 Comment(2)
Yes. As answered in this questionEverrs
Indeed, passing the proper arguments when creating the widget is an excellent suggestion. ;¬)Gagger
G
6

Late answer..

Just use

self.option = OptionMenu(PARENT, VALUE TO BE CHANGED, "DEFAULT TEXT", *OPTIONS_ARRAY/LIST)

Works perfectly for me.

Goodtempered answered 13/6, 2014 at 15:44 Comment(0)
M
0

Never mind, I took the *userList off and used a for loop to insert the items as commands. Now it works just fine.
The code I used:

for user in userList:
    usersOption["menu"].insert("end", "command", label=user, command=_setit(z, user, changeUser))
Mancini answered 13/5, 2013 at 22:28 Comment(1)
IMO, this is a very hacky way of doing things because it's making use of the private _setit() function defined in the module. Since you obviously peeked at the source code, why not just pass the proper arguments to the widget's constructor instead?Gagger

© 2022 - 2024 — McMap. All rights reserved.