Графический интерфейс Tkinter, перекрывающий или обновляющий метки из списка

1

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

Мой список, 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()
  • 0
    Когда должна произойти эта очистка?
  • 0
    @martineau В идеале каждый раз, когда пользователь нажимает кнопку, список очищается и перепечатывается.
Теги:
tkinter

1 ответ

2
Лучший ответ

Для того, чтобы делать то, что вы хотите, я добавил еще один 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()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню