Я пытаюсь создать графический интерфейс, где пользователь может выбирать элементы из списка с возможностью прокрутки, но у меня возникают проблемы с печатью выбранных элементов после выбора кнопок. Когда я запускаю следующий код, ярлык в конце, который выводит на печать то, что выбрал пользователь, не обновляется. Так что, если пользователь передумает, выберет разные фрукты, а затем снова нажмет кнопку, графический интерфейс не отразит это.
Мой список, check_list
, изменяется соответствующим образом, но мне в основном нужен способ очистить графический интерфейс и снова пометить. Я чувствую, что простой способ сделать это - забыть фрейм (т.е. frame.pack_forget()
), но мне пока не повезло с этим.
import tkinter as tk
from tkinter import *
mylist = ['apple','pear','kiwi','banana','strawberry','pineapple']
root = Tk()
root.geometry('400x100')
frame = Frame(root)
frame.pack(fill=BOTH, expand = True)
fruit_vars = []
check_list= []
def cb_checked():
global check_list
for ctr, int_var in enumerate(fruit_vars):
if int_var.get(): ## IntVar not zero==checked
temp = mylist[ctr]
check_list.append(temp)
#Keep only the unique fruits in list
check_list_set = set(check_list)
check_list = list(check_list_set)
return check_list
#Create scrollable checkboxes of fruit options
text = tk.Text(root, cursor="arrow", width = 5, height = 5)
vsb = tk.Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=vsb.set)
vsb.pack(side="right", fill="y")
text.pack(side="left", fill="both", expand=True)
for fruit in mylist:
fruit_vars.append(tk.IntVar())
cb = tk.Checkbutton(text, text=fruit, variable=fruit_vars[-1],
onvalue=1, offvalue=0, command=cb_checked)
text.window_create("end", window=cb)
text.insert("end", "\n")
#Print which fruits the user chose to the gui
def label_fruits():
print(check_list)
for fruits in check_list:
Label(root, text=fruits).pack()
Button(root, text='Show Chosen Fruits', command=label_fruits).pack()
root.mainloop()
Для того, чтобы делать то, что вы хотите, я добавил еще один list
, названный check_buttons
, чтобы сохранить tkinter
идентификаторы каждого tk.Checkbutton
созданного. Это позволяет каждый из них может быть очищен позже.
Я также добавил еще один объект-контейнер Frame
для хранения всех названий фруктов с Label
. Он был создан на лету в label_fruits()
после первой попытки избавиться от любого существующего, вызвав list_frame.destroy()
. Затем он (заново) создается и в него помещается новый набор Label
.
import tkinter as tk
mylist = ['apple', 'pear', 'kiwi', 'banana', 'strawberry', 'pineapple']
root = tk.Tk()
root.geometry('400x100')
frame = tk.Frame(root)
frame.pack(fill=tk.BOTH, expand=True)
checked_list = []
check_buttons = [] # Added.
fruit_vars = []
def cb_pressed():
""" Checkbutton callback. """
# (Re)create [the entire] list of checked fruits.
checked_list.clear()
for i, int_var in enumerate(fruit_vars):
if int_var.get(): # Not zero -> checked.
checked_list.append(mylist[i])
# Create scrollable Checkbuttons of fruit options.
text = tk.Text(root, cursor="arrow", width=5, height=5)
vsb = tk.Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=vsb.set)
vsb.pack(side=tk.RIGHT, fill=tk.Y)
text.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)
# Create IntVars and check_buttons list.
for fruit in mylist:
fruit_vars.append(tk.IntVar())
cb = tk.Checkbutton(text, text=fruit, variable=fruit_vars[-1],
onvalue=1, offvalue=0, command=cb_pressed)
check_buttons.append(cb)
text.window_create(tk.END, window=cb)
text.insert(tk.END, "\n")
def label_fruits():
""" Display the fruits user has checked. """
global list_frame
print(checked_list)
try:
list_frame.destroy()
except NameError: # Nonexistent.
pass
list_frame = tk.Frame(root) # (Re)create Label container.
list_frame.pack()
for fruit in checked_list:
tk.Label(list_frame, text=fruit).pack()
# Clear out GUI by unchecking all the Checkbuttons.
for cb in check_buttons:
cb.deselect()
tk.Button(root, text='Show Chosen Fruits', command=label_fruits).pack()
root.mainloop()