Chris Nicholson
Chris Nicholson

Reputation: 1

Tkinter frame alignment (grid layout)

In Python/Tkinter, I am trying to get a value (integer) from a frame, do a calculation on it and return it as an output. I was able to make it work when using only a master frame and putting everything in that one frame. Now I want to separate it and another operation into their own frames.

My program converts board feet to Lineal feet (frame A) and Lineal feet to board feet (frame B).

I get errors like: NameError: global name 'b_entry' is not defined. I have a feeling I might be doing things like referencing frames (self, master, a_frame, etc.) improperly.

Here's a simple example:

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()

Upvotes: 0

Views: 542

Answers (1)

Kevin
Kevin

Reputation: 76194

I see two issues.

  • You should not assign a widget to a variable and pack/grid it on the same line. This causes the variable to have a value of None, because that's what pack and grid return. This will screw up your widget hierarchy because when b_frame is None, tk.Label(b_frame, ... will make the label a child of the Tk window instead of the Frame.
  • If you want a variable to be visible in all of a class' methods, you should assign it as an attribute of self.

So you should change lines like

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

To

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

Then you will be able to properly reference the entry in convert.

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

Upvotes: 1

Related Questions