Как получить список текстовых значений нескольких Checkbuttons в Tkinter в Python? - PullRequest
2 голосов
/ 29 марта 2012

Используя следующий код, я пытаюсь получить обновленный список соответствующих текстовых значений флажков, каждый раз, когда флажок проверяется или не проверяется:

import Tkinter as tk

opt = []
def chkbox_checked():
    for ix, item in enumerate(cb):
        opt.append(cb_v[ix].get())
    print opt
root = tk.Tk()
mylist = [
'NR',
'ECEF X',
'ECEF Y',
'ECEF Z',
'height'
]
cb = []
cb_v = []
for ix, text in enumerate(mylist):
    cb_v.append(tk.StringVar())
    cb.append(tk.Checkbutton(root, text=text, onvalue=text, variable=cb_v[ix],   comand=chkbox_checked))
    cb[ix].grid(row=ix, column=0, sticky='w')   
label = tk.Label(root, width=20)
label.grid(row=ix+1, column=0, sticky='w')
root.mainloop()

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

['NR']
['NR','ECEF X]
['NR','ECEF X','ECEF Y']
['NR','ECEF X','ECEF Y','ECEF Z]
['NR','ECEF X','ECEF Y','ECEF Z','height',]

но с приведенным выше кодом я получаю умноженный вывод, а также что-то не так с самими кнопками проверки, их состояние проверяется с самого начала. Любая помощь будет оценена.

1 Ответ

5 голосов
/ 29 марта 2012

Одной из проблем, описанных выше, является opt.append в chkbox_checked ... Так как эта функция вызывается каждый раз, когда кнопка отмечена / не отмечена, длина списка опций будет увеличиваться на количество кнопок, которые вы имеете каждый раз, когда одна из кнопок кнопки нажимаются. Решение (опубликовано ниже) - инициализировать opt при создании кнопок, а затем просто обновить их элементы в chkbox_checked. Что касается состояния кнопок при создании, я не уверен, почему они изначально проверены, но вы также можете легко отменить выбор кнопок при инициализации, используя метод отмены выбора.

import Tkinter as tk

opt = []
def chkbox_checked():
    for ix, item in enumerate(cb):
        opt[ix]=(cb_v[ix].get())
    print opt
root = tk.Tk()  
mylist = [
'NR',
'ECEF X',
'ECEF Y',
'ECEF Z',
'height' 
]
cb = []
cb_v = []
for ix, text in enumerate(mylist):
    cb_v.append(tk.StringVar())
    off_value=0  #whatever you want it to be when the checkbutton is off
    cb.append(tk.Checkbutton(root, text=text, onvalue=text,offvalue=off_value,
                             variable=cb_v[ix],
                             command=chkbox_checked))
    cb[ix].grid(row=ix, column=0, sticky='w')
    opt.append(off_value)
    cb[-1].deselect() #uncheck the boxes initially.
label = tk.Label(root, width=20)
label.grid(row=ix+1, column=0, sticky='w')
root.mainloop()

Еще один полезный прием - вместо того, чтобы хранить 2 списка (cb и cb_v), вы можете просто добавить StringVars в качестве атрибутов для своих кнопок. e.g.:

v=tk.StringVar()
cb.append(tk.CheckButton(... , variable=v, ...)
cb[-1].v=v

Тогда у вас есть только один список со всеми данными. Соответствующий chkbox_checked будет выглядеть так:

def chkbox_checked():
   opt=[chkbox.v.get() for chkbox in cb]
   print opt

(обратите внимание, это также устраняет необходимость в глобальном списке opt ... хотя, возможно, существует целый ряд других способов избавиться от этого списка)

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