4
\$\begingroup\$

I am making a GUI application for a class. I have made the form layout (make_form()) using both Frame and grid, but I am not exactly sure that one should be mixing those two together. What is the best way to make a layout, using grid to incorporate not just the labels and Entry fields, but also the buttons?

import tkinter as tk
fields = "Dimensions", "Parent population size", "Children populatoin size", \
 "Recombination population size", "Maximum iterations", "Low boundary domain", \
 "High boundary domain", "Parameter size"
def quit():
 root.destroy()
def clear_initial_conditions(initial_conditions):
 for ic in initial_conditions:
 ic[1].delete(0, "end")
def get_initial_conditions(initial_conditions):
 for ic in initial_conditions:
 field = ic[0]
 text = ic[1].get()
 if text.isdigit():
 print("%s: %s" % (field, text))
 else:
 print("Field \"%s\" does not have a valid number, correct to integer" % field)
def make_form(root, fields):
 initial_conditions = []
 for field in fields:
 row = tk.Frame(root)
 row.pack(side = tk.TOP, fill = tk.X, padx = 10, pady = 10)
 lab = tk.Label(row, width = 30, text = field, anchor = tk.W)
 lab.grid(row = 0, column = 0)
 ent = tk.Entry(row)
 ent.grid(row = 0, column = 1, sticky = tk.W)
 initial_conditions.append((field, ent))
 return initial_conditions 
if __name__ == "__main__":
 root = tk.Tk()
 root.option_add('*font', ('verdana', 8))
 root.title("Pack - Example 12")
 ents = make_form(root, fields)
 root.bind("<Return>", (lambda event, e = ents: get_initial_conditions(e)))
 b1 = tk.Button(root, text = "Find minimum", command = (lambda e = ents: get_initial_conditions(e)))
 b1.pack(side = tk.LEFT, padx = 10, pady = 10)
 b2 = tk.Button(root, text = "Clear", command = (lambda e = ents: clear_initial_conditions(e)))
 b2.pack(side = tk.LEFT, padx = 10, pady = 10)
 root.mainloop()
200_success
146k22 gold badges190 silver badges478 bronze badges
asked Dec 4, 2017 at 9:01
\$\endgroup\$
1
  • \$\begingroup\$ Your question is unclear. Frame and grid are explicitly designed to work together. Also, what do you mean by "using grid to incorporate not just the labels and Entry fields, but also the buttons?" If you want to use grid with buttons, just call grid on the buttons. \$\endgroup\$ Commented Dec 4, 2017 at 15:26

1 Answer 1

1
\$\begingroup\$

Frames are specifically designed to be a tool in organizing the widgets in your GUI.

In the case of a simple form like this, I recommend using one frame for the labels and entries, and one for the buttons. grid is the natural choice for the form, and it looks like pack would be best for the buttons. pack is also best to put the form on top and the buttons on the bottom.

For the form, I would not use a frame for each row.

Example:

# the root window and its children
form = tk.Frame(root)
buttons = tk.Frame(root)
form.pack(side="top", fill="both", expand=True)
buttons.pack(side="bottom", fill="x")
# the buttons
b1 = tk.Button(buttons, ...)
b2 = tk.Button(buttons, ...)
b1.pack(side="left", ...)
b2.pack(side="left", ...)
# the form
for row, field in enumerate(fields):
 lab = tk.Label(form, ...)
 ent = tk.Entry(form, ...)
 lab.grid(row=row, column=0, ...)
 ent.grid(row=row, column=1, ...)

The form can be thought of as a single complex widget. You can do that by creating a class for the form, based off of the Frame widget:

class Form(tk.Frame):
 def __init__(self, parent, fields):
 tk.Frame.__init__(self, parent)
 for row, field in enumerate(fields):
 ...

You would then use it like a normal frame when adding it to the window:

form = Form(root, fields=fields)
...
form.pack(side="top", fill="both", expand=True)

With that, you now have a general purpose form that could be reused for different purposes with different sets of fields.

answered Dec 4, 2017 at 15:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.