如何真正破坏一个框架,使它消失

问题描述 投票:1回答:2

我有一个小程序在数据库中进行搜索并显示结果。我的计划是将结果显示在放置搜索参数的同一窗口中的适当大小的框架中。

由于我想替换每个新查询的结果,因此我有一个results_owner框架,该框架是永久性的,并且具有一个子result_frame,该框架根据需要进行填充和销毁。至少,这是计划。它进展不顺利。

我可以创建框架并将内容放入其中。但是当我想删除或替换它时,我留下了前一个化身的东西。有些东西被修改了,有些东西似乎是永久性的,它让我感到困惑。

你可能需要让窗户更高才能看到完整的效果。基本缺陷是,当您单击“线+”按钮时,显示的行是永久性的,因此当您单击“新框架”按钮时,线条应该消失但不会消失。

这是代码:

#!/usr/bin/env python3
"""Find a matching record in the database

Last Modified: Fri Dec 15 18:20:32 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self._create_widgets()

    results_owner = None
    results_frame = None
    iteration = 0

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=(lambda arg=self.results_frame: self.addline(arg)))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root)
        self.results_owner.pack(side=tk.TOP, fill=tk.X)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.LEFT, padx=5, pady=5)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=0, pady=self.iteration)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        print("addline")
        msg = "New Line"
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()

这是使用注释中的一些建议修改的代码(但它仍然无法按预期工作):

#!/usr/bin/env python3
"""Find a matching record in the database

Last Modified: Fri Dec 15 20:31:17 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self.results_owner = None
        self.results_frame = None
        self.iteration = 0
        self._create_widgets()

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=self.addline(self.results_frame))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root)
        self.results_owner.pack(side=tk.TOP, fill=tk.X)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.pack_forget()
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.LEFT, padx=5, pady=5)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=0, pady=self.iteration)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        print("addline")
        msg = "New Line" + str(self.iteration)
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()
python-3.x tkinter widget
2个回答
1
投票

在你的情况下,你必须直接在lambda中使用self.results_frame

command=lambda:self.addline(self.results_frame) 

始终访问变量self.results_frame中的当前值

arg=self.results_frame中使用lambda

lambda arg=self.results_frame: self.addline(arg)

您只需将值从self.results_frame复制到arg一次(开始时),之后函数始终使用相同的值。


1
投票

事实证明我必须调用addline一个lambda;事实上,该功能只被调用一次。我还调整了包装和边框,以明确事情是如何分组的。我现在可以将它用作我的应用程序的模型。

#!/usr/bin/env python3
"""Last Modified: Sat Dec 16 07:28:31 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self.results_owner = None
        self.results_frame = None
        self.iteration = 0
        self._create_widgets()

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=(lambda :self.addline(self.results_frame)))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root, borderwidth=3, relief=tk.RAISED)
        self.results_owner.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner, borderwidth=1, relief=tk.GROOVE)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=2, pady=2)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        msg = "New Line" + str(self.iteration)
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        self.root.update_idletasks()
        self.iteration += 1

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.