【问题标题】:Dynamically adding and deleting entry boxes Tkinter动态添加和删除条目框 Tkinter
【发布时间】:2018-10-30 02:16:02
【问题描述】:

我正在尝试制作一个 gui,它根据用户选择的统计分布类型为用户提供一系列输入框。这将在脚本稍后的计算中使用。每个统计分布需要不同数量的变量(因此需要动态填充多个输入框)。现在我的代码有点工作。问题是,如果您选择一个提供 5 个输入框的分布,然后将分布切换到只需要 3 个的分布,则之前选择的 5 个框仍然存在。对于这个脚本,截断正态分布应该有 3 个变量,正态分布应该有 5 个变量,离散分布应该有 4 个变量。

我认为如果我创建了一个虚拟输入框,然后在 if 语句的末尾将其删除,它最终会删除我不需要的框。但这似乎不起作用。

下面是我到目前为止的代码。我觉得我快到了,只是错过了一些东西。我将不胜感激任何建议。同样,目标是为每个统计分布选择填充正确数量的输入框,然后能够动态更改该选择并相应地更改输入框的数量。

import tkinter as tk
from tkinter.ttk import *

master = tk.Tk()
master.title("Gas Calculator")
v = tk.IntVar()
combo = Combobox(master)

def callbackARS(eventObject):
    ARDist=(comboARS.get())


    if ARDist == "Truncated Normal":
        a1 = tk.Entry(master)
        a2 = tk.Entry(master)
        a3 = tk.Entry(master)
        #attempt to create a dummy input box that isnt needed and then delete it at the end of the code
        a4 = tk.Entry(master)
        a1.grid(row=3, column=4)
        a2.grid(row=3, column=5)
        a3.grid(row=3, column=6)
        a4.grid(row=3, column=7)
        tk.Label(master, text="Variable", padx=20, width=10, bg = "light blue").grid(row=2,column=4)
        tk.Label(master, text="Area", padx=20, width=10, bg = "light blue").grid(row=2,column=5)
        tk.Label(master, text="Thickness", padx=20, width=10, bg = "light blue").grid(row=2,column=6)
        tk.Label(master, text="", padx=20, width=10, bg = "light blue").grid(row=2,column=7)
        #attempt to create a dummy input box that isnt needed and then delete it at the end of the code
        a4.grid_remove()

    if ARDist == "Normal":
        b1 = tk.Entry(master)
        b2 = tk.Entry(master)
        b3 = tk.Entry(master)
        b4 = tk.Entry(master)
        b5 = tk.Entry(master)
        b1.grid(row=3, column=4)
        b2.grid(row=3, column=5)
        b3.grid(row=3, column=6)
        b4.grid(row=3, column=7)
        b5.grid(row=3, column=8)
        tk.Label(master, text="a", padx=20, width=10, bg = "light blue").grid(row=2,column=4)
        tk.Label(master, text="Aa", padx=20, width=10, bg = "light blue").grid(row=2,column=5)
        tk.Label(master, text="aaa", padx=20, width=10, bg = "light blue").grid(row=2,column=6)
        tk.Label(master, text="aaaa", padx=20, width=10, bg = "light blue").grid(row=2,column=7)

    if ARDist == "Discrete":
        a1 = tk.Entry(master)
        a2 = tk.Entry(master)
        a3 = tk.Entry(master)
        a4 = tk.Entry(master)
        a1.grid(row=3, column=4)
        a2.grid(row=3, column=5)
        a3.grid(row=3, column=6)
        a4.grid(row=3, column=7)

#Distribution selction
comboARS = Combobox(master)
comboARS['values']= ("Truncated Normal", "Normal", "Discrete")
comboARS.current(0) #set the selected item
comboARS.grid(row=3, column=3)
comboARS.bind("<<ComboboxSelected>>", callbackARS)

【问题讨论】:

  • 您的代码中似乎没有任何地方可以在创建新条目之前删除旧条目小部件。每次调用您的函数时,您都会创建更多小部件。
  • 我运行了您的代码并选择了“截断正常”。我在第 2 行看到四个标签,第四个是空白的。第 3 行中有 3 个条目,这正是您在调用 grid_remove() 后所期望的。问题是什么?顺便说一句,grid_remove 不会删除对象,它只是使其不可见。
  • 对于这个脚本,截断的正态分布应该有 3 个变量:那为什么在你的代码中有 4 个条目和 4 个标签呢?
  • @PaulCornelius 尝试在变量之间切换,您会看到,一旦您选择输入框数量最多的选项,然后尝试切换到输入框较少的选项,它不会删除不必要的输入框
  • @BillalBEGUERADJ 那是我试图诱使 python 做我想做的事情的尝试。我认为如果我给它一个虚拟输入框,它最终会删除我在选择之间切换时不需要的输入框。显然没有用。

标签: python python-3.x tkinter


【解决方案1】:

如果您在框架中创建一组标签和输入字段,您可以轻松地操纵它们的属性和可见性。 grid_remove() 和 winfo_children() 方法的组合非常有用。

import tkinter as tk
from tkinter import ttk

master = tk.Tk()
my_frame = tk.Frame()
my_frame.grid(row=0, column=1)
# create one set of widgets in a frame
for num in range(1, 6):
    tk.Label(master=my_frame).grid(row=0,column=num)
    tk.Entry(master=my_frame).grid(row=1, column=num)
def detect_selection(eventobject):
    the_selection = eventobject.widget.get()
    # hide all widgets
    for item in my_frame.winfo_children():
        item.grid_remove()
    show_idx__wigets = 6
    if the_selection == '3':
        change_labeltext(('a', 'b', 'c'), 6)
    if the_selection == '4':
        show_idx__wigets = 8
        change_labeltext(('d', 'e', 'f', 'g'), 8)
    if the_selection == '5':
        show_idx__wigets = 10
        change_labeltext(('h', 'i', 'j', 'k', 'l'), 10)
    # reveal only desired number of widgets
    show_widgets(show_idx__wigets)

def show_widgets(upto_widgetposition):
    for item in my_frame.winfo_children()[:upto_widgetposition]:
        item.grid()
def change_labeltext(labeltext, upto_widgetposition):
    for txt, item in zip(
        labeltext, my_frame.winfo_children()[:upto_widgetposition:2]):
        item['text'] = txt    
combo = ttk.Combobox(master,
                     values=(3,4,5))
combo.grid(row=0, column=0, sticky='s')
combo.bind('<<ComboboxSelected>>', detect_selection)

master.mainloop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    相关资源
    最近更新 更多