2015-07-29 7 views
0

Я пытаюсь создать выпадающий список для личной программы, который автоматически обновляет отображаемое имя на основе выбранного элемента.Создание выпадающего пункта меню Python

Дело в том, что независимо от того, что выбрано или какое значение по умолчанию должно быть, оно всегда автоматически изменяет выбранное имя на последний параметр, который пользователь может выбрать, и он не изменится, если выбран другой параметр.

import tkinter 
from tkinter import * 


def changename(name=str): 
    selectedText.set(name) 
    mb.grid(row=1,column=1) 
def startmainloop(var): 
    var.mainloop() 



root = Tk() 

label0=Label(root,text=".....") 
label0.grid(row=0,columnspan=2) 

selectedText=StringVar() 
selectedText.set("Select Race") 
mb=Menubutton(root, textvariable=selectedText,relief=GROOVE) 
label1=Label(root, text="RACE") 
label1.grid(row=1,column=0) 
mb.grid() 
mb.menu=Menu(mb, tearoff=0) 

mb.menu.add_command(label="Argonian", command=changename("Argonian")) 
mb.menu.add_command(label="Khajiit", command=changename("Khajiit")) 

mb["menu"]=mb.menu 

startmainloop(root) 

На изображении, которое было бы выше, по умолчанию он должен показывать «Выбрать расу». Выпадающее меню появляется после нажатия на Select Race с двумя параметрами команды «Argonian» и «Khajiit». После нажатия на опцию «Argonian» метка «Выбрать раса» меню должна измениться на «Argonian». Опция «Khajiit», по-видимому, перегружает значение по умолчанию и не будет меняться независимо от пользователя, выбирающего Argonian.

+0

У вас возникли ошибки относительно не b возможно ли назвать «Nonetype»? – TigerhawkT3

+0

нет, если я отформатирую его так, если я поставлю «StringVar()» перед «root = Tk()», тогда да, я получил эту ошибку – AZLord

+0

Вы должны получить такую ​​ошибку из 'command = changename (« Argonian »)) ', когда вы выбираете этот пункт меню, потому что он попытается вызвать' None', который не работает. – TigerhawkT3

ответ

1

Когда вы указываете значение аргумента таким образом command=changename("Khajiit"), он вызывает функцию справа, а его значение возвращается (None) в качестве значения аргумента. Это очень распространенная ошибка программирования Tkinter.

Сделайте что-нибудь, как это вместо:

mb.menu.add_command(label="Argonian", command=lambda: changename("Argonian")) 
mb.menu.add_command(label="Khajiit", command=lambda: changename("Khajiit")) 

Это сделает значения, переданные в качестве аргумента command анонимных функций, которые вызывают вашу функцию обработчика с правым аргументом.

Возможно, лучше, как и в более общем и менее повторяющемся подходе, было бы изменить функцию changename(), чтобы он получил метку самой команды, тогда вам нужно будет только указать строку один раз.

Другими словами, сделать что-то вроде этого:

def changename(index): 
    name = mb.menu.entrycget(index, "label") 
    selectedText.set(name) 
    mb.grid(row=1, column=1) 

, который позволил бы вам просто передать индекс элемента:

mb.menu.add_command(label="Argonian", command=lambda: changename(0)) 
mb.menu.add_command(label="Khajiit", command=lambda: changename(1)) 

Чтобы избежать необходимости явно рассчитывать и жёстко индекс каждой команды, это можно сделать в петле for:

for i, label in enumerate(["Argonian", "Khajiit"]): 
    mb.menu.add_command(label=label, command=lambda: changename(i)) 
+0

Я использую Python 3.4.3, так что есть другой способ, которым я должен форматировать «command = lambda event: changename (...» Я получаю эту ошибку, используя ее с вашим синтаксисом Исключение в обратном вызове Tkinter Traceback (последний последний звонок): Файл «C: \ ....», строка 1533, в __call__ ТипError: () отсутствует 1 обязательный позиционный аргумент: 'event' – AZLord

+0

К сожалению, я думал о событии виджета обработчики, которые автоматически получают переданный аргумент 'event', когда они вызываются. Аргумент' command' элемента добавленной команды меню - это просто процедура, которая будет вызвана (без аргументов) всякий раз, когда элемент меню будет выбран. См. обновленный ответ (который теперь также включает альтернативу). – martineau

Смежные вопросы