简体   繁体   English

Tkinter GUI重叠或刷新列表中的标签

[英]Tkinter GUI overlapping or refreshing labels from a list

I'm trying to have a gui where the user can choose items from a scrollable list, but I'm having trouble printing out the chosen items once the checkbuttons have been selected. 我正在尝试创建一个gui,用户可以在其中从滚动列表中选择项目,但是一旦选中了选择按钮,我就无法打印出所选择的项目。 When I run the following code, the label I have at the end that prints out what the user selected doesn't refresh. 当我运行以下代码时,我最后打印出用户所选内容的标签不会刷新。 So if the user changes their mind, picks different fruits, and then hits the button again, the gui doesn't reflect that. 因此,如果用户改变主意,采摘不同的水果,然后再次按下按钮,则gui不会反映出来。

My list, check_list , changes appropriately, but I basically need a way to clear out the GUI and label again. 我的清单check_list适当的更改,但是我基本上需要一种清除GUI并再次标记的方法。 I feel like an easy way to do this would be to forget the frame (ie frame.pack_forget() ), but I haven't had any luck with it so far. 我觉得一个简单的方法就是忘记框架( 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()

To do what you want, I added another list , named check_buttons , to retain the tkinter ids of each tk.Checkbutton created. 要做到你想要什么,我增加了一个list ,命名check_buttons ,保留tkinter每个IDS tk.Checkbutton创建。 This allows each one can be cleared later. 这样可以使每个人以后都可以清除。

I also added another Frame container object to hold all the fruit name Label s. 我还添加了另一个Frame容器对象,以容纳所有水果名称Label It's created on-the-fly in label_fruits() after first making an attempt to get rid of any existing one by calling list_frame.destroy() . 它是在尝试通过调用list_frame.destroy()摆脱所有现有label_fruits()后,在label_fruits()即时创建的。 It's then (re)created and a new set of Label s are put in it. 然后(重新)创建它,并放入一组新的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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM