【问题标题】:Tkinter frame alignment (grid layout)Tkinter 帧对齐(网格布局)
【发布时间】:2015-08-07 13:09:11
【问题描述】:

在 Python/Tkinter 中,我试图从帧中获取一个值(整数),对其进行计算并将其作为输出返回。当我只使用一个主框架并将所有东西都放在那个框架中时,我能够让它工作。现在我想将它和另一个操作分离到它们自己的框架中。

我的程序将板英尺转换为线性英尺(框架 A)和 直线脚到板脚(框架 B)。

我收到如下错误:NameError: global name 'b_entry' is not defined。我有一种感觉,我可能会不正确地引用框架(self、master、a_frame 等)。

这是一个简单的例子:

import Tkinter as tk

class App:
    def __init__(self, master):
        self.master = master
        master.grid()

        b_frame = tk.Frame(master).grid(row=0)
        b_name = tk.Label(b_frame, text='Blah').grid(row=1, columnspan=4)
        b_label = tk.Label(b_frame, text='Label').grid(row=2, column=0)
        b_entry = tk.Entry(b_frame).grid(row=2, column=1)
        b_output = tk.Label(b_frame, text='Output')
        b_output.grid(row=3, columnspan=2)
        b_button = tk.IntVar()
        tk.Button(b_frame, text='calc', command=self.convert).grid(row=4, columnspan=2)

    def convert(self):
        a = int(b_entry.get())
        result = int(a * a)
        b_output.configure(text=result)

root = tk.Tk()
App(root)
root.mainloop()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    我看到了两个问题。

    • 您不应将小部件分配给变量并将其打包/网格在同一行。这会导致变量的值为None,因为这是packgrid 返回的值。这将搞砸您的小部件层次结构,因为当 b_frame 为 None 时,tk.Label(b_frame, ... 将使标签成为 Tk 窗口而不是 Frame 的子级。
    • 如果您希望变量在类的所有方法中可见,则应将其分配为self 的属性。

    所以你应该换行像

    b_entry = tk.Entry(b_frame).grid(row = 2, column = 1)
    

    self.b_entry = tk.Entry(b_frame)
    self.b_entry.grid(row = 2, column = 1)
    

    然后您将能够正确引用convert中的条目。

    a = int(self.b_entry.get())
    

    【讨论】:

    • 啊,好的。这太有趣了。前几天我正在分离包/网格代码。我确实注意到尝试对其进行配置之类的操作会引发错误。在搜索 SO 时,我确实找到了该问题的答案。诚然,将它们组合起来我有点懒惰,以为我会节省一些打字,但现在你提到它,调试有点困难。我应该在每一行之前加上'.self',还是只在需要调用的行之前?
    • 这很有名!我真的很感激这些信息。我基本上一直在自学,使用 SO 和 Youtube 进行指导。我发现它可以帮助我对源示例进行逆向工程并尝试将它们重新实现到我的代码中。大多数时候它是有效的,或者至少给了我一个起点去尝试看看什么有效,什么无效。我想有时你只需要一个直接问题的直接答案。感谢您的帮助和时间。我真的很感激。
    • "我应该在每一行之前加上'self',还是只在需要调用的行之前?"您只需必须self. 放在您希望通过其他方法或完全在课堂之外访问的作业之前。然而,有些人会将它们放在每一项任务的前面,可能是出于审美原因,或者是因为他们认为以后可能需要这些值。这主要是个人喜好问题。