如何使用另一个按钮隐藏使用命令按钮生成的标签?

时间:2018-03-10 14:56:06

标签: python python-3.x user-interface tkinter

问题(故事):

我在一个条目小部件里写,然后我按下一个按钮,窗口中出现一个新标签,上面有我输入的文字。然后我按下一个不同的按钮,期望的结果是生成的标签消失但是,我收到一条错误消息。

为什么我要这样做?

我想创建一个用于进行SQL查询的接口,我正在尝试实现的过程是:

  • 用户在条目小部件中输入字符串。
  • 用户按下“搜索”按钮以执行查询。
  • 界面返回结果。 (我已经实现了这一点 LabelFrameFrame小部件)。
  • 用户按下“清除”按钮并生成所有小部件 消失,界面已准备好进行新查询。

不隐藏的标签(代码):

from tkinter import *

root = Tk()

pacienteLabel = Label(text="Paciente: ")
pacienteLabel.grid()

pacienteEntry = Entry()
pacienteEntry.grid()

profesionalLabel = Label(text="Profesional: ")
profesionalLabel.grid()

profesional = StringVar()
# Here I capture the string that I want to show:
profesionalEntry = Entry(textvariable=profesional)
profesionalEntry.grid()

def ver():
    # This label is generated without problems: 
    newLabel = Label(text="hola profesional: {}".format(profesional.get()))
    newLabel.grid()
    # When I was trying to figure out what was happening I added this:
    print(newLabel)
    # And the output is:
    # .!label4 
    # I have read through documentation why is this but I couldn't find why.


buscarButton = Button(text="Buscar", command=ver)
buscarButton.grid()


def borrar():
    # After that I saw the previous output from print was obvious why the
    # next line don't work:
    newLabel.grid_forget()

borrarButton = Button(text="Borrar", command=borrar)
borrarButton.grid()

root.mainloop()

下图显示了错误和GUI:

Error & GUI

最后,我在这里读到了什么:

最后,如果你正在阅读这个问题,谢谢你的时间!

1 个答案:

答案 0 :(得分:0)

您可以将global newLabel添加为def ver():的第一行,但这样您就可以隐藏您创建的最后一个标签,递归。原因是您没有为前一个标签对象留下任何参考,但它们仍然存在,但它们不能很容易地被引用。相反,我会提供一个答案的答案:

  

“如何使用其他按钮隐藏使用命令按钮生成的标签?”

可以对窗口小部件执行各种操作(标签是窗口小部件),只要它们具有有效的引用(您的newLabel引用会被覆盖)。只要它们具有参考,它们如何被创建并不重要。在下面的示例中,有一个button_that_creates_labels,一个button_that_hides_labels,一个entry,可让用户设置新标签的文字。 button_that_hides_labels隐藏了最后添加的标签,递归

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def create_new_label(parent, widget_list, entry, button):
    widget_list.append(tk.Label(parent, text=entry.get()))
    widget_list[-1].grid(columnspan=2)
    button['command'] = lambda w=widget_list, i=-1, b=button: \
        hide_the_last_label(w, i, b)


def hide_the_last_label(widget_list, index, button):
    if len(widget_list) >= abs(index):
        widget_list[index].grid_remove()
        button['command'] = lambda w=widget_list, i=index-1, b=button: \
            hide_the_last_label(w, i, b)


def main():
    root = tk.Tk()
    # This list will contain all widgets objects generated during the
    # execution of the lambda expression.
    labels = list()
    entry = tk.Entry(root)
    button_that_hides_labels = tk.Button(root, text="Hide")
    # A lambda expression to prevent call the function before the
    # button has been pressed.
    button_that_creates_labels = tk.Button(root, text="Create",
        command=lambda p=root, wl=labels, e=entry, b=button_that_hides_labels\
                                            : create_new_label(p, wl, e, b))
    button_that_hides_labels['command'] = lambda w=labels, i=-1, \
                    b=button_that_hides_labels:hide_the_last_label(w, i, b)
    button_that_creates_labels.grid(row=1, column=0)
    button_that_hides_labels.grid(row=1, column=1)
    entry.grid(row=0, column=0, columnspan=2)
    tk.mainloop()

if __name__ == '__main__': main()

然而,如果你想摧毁&删除而不是隐藏,我的实现会简单得多:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


def create_new_label(parent, widget_list, entry):
    widget_list.append(tk.Label(parent, text=entry.get()))
    widget_list[-1].grid(columnspan=2)


def remove_the_last_label(widget_list):
    if widget_list:
        # Here the widget don't show up
        widget_list[-1].destroy()
        # If the item is not removed from the list, white spaces will remain
        # in the window.
        del widget_list[-1]


def main():
    root = tk.Tk()
    labels = list()
    entry = tk.Entry(root)
    button_that_hides_labels = tk.Button(root, text="Hide")
    button_that_creates_labels = tk.Button(root, text="Create",
        command=lambda p=root, wl=labels, e=entry: create_new_label(p, wl, e))
    button_that_hides_labels['command'] = lambda w=labels: \
                                                    remove_the_last_label(w)
    button_that_creates_labels.grid(row=1, column=0)
    button_that_hides_labels.grid(row=1, column=1)
    entry.grid(row=0, column=0, columnspan=2)
    tk.mainloop()

if __name__ == '__main__':
    main()