Fixed code
import tkinter as tk
from tkinter import Entry, Frame, Label, Tk
class Input_screen:
def __init__(self,master):
frame = Frame(master)
frame.grid(column=1)
# frame.pack()
self.name_label = Label(frame, text = 'NAME')
self.name_entry = Entry(frame)
self.name_label.grid(row=1, column=0, sticky='w')
self.name_entry.grid(row=1, column=1, sticky='w')
root = Tk()
width = 200
length = 100
root.geometry(f"""{width}x{length}""")
b = Input_screen(root)
root.mainloop()
Changes:
- Write
frame.grid(column=1)
to allow columns 0 and 1 for the two widgets in that frame.
- Both widgets are now in the Frame
frame
, see Entry(frame)
.
- And the
sticky
parameter must be quoted.
Code output:
If you add the Entry widget only to the root window, and not to its frame, as is done in the code of the question (Entry(frame)
), you will not see the output in the needed two columns anymore since the two widgets (Label and Entry) are not in the same frame anymore:
If you do not need a frame at all since everything fits in the main window, you can drop the frame from the code, and the default grid of the root window works fine and has the same output:
import tkinter as tk
from tkinter import Entry, Frame, Label, Tk
class Input_screen:
def __init__(self,master):
self.name_label = Label(master, text = 'NAME')
self.name_entry = Entry(master)
self.name_label.grid(row=1, column=0, sticky='w')
self.name_entry.grid(row=1, column=1, sticky='e')
root = Tk()
width = 200
length = 100
root.geometry(f"""{width}x{length}""")
b = Input_screen(root)
root.mainloop()
More on sticky
The sticky
parameter only puts the "sides and corners of the cell" that the widget shall stick to: north, east, south and/or west, see Python tkinter how to use grid sticky. For more, see How does the sticky command affect the python code in Tkinter?. It does not influence the GUI as it is now since it only works if there's more room for the widget than needed, and the frame at hand has only one row, there is no other widget in the same column that is wider. That is why you could also drop the sticky parameter and get the same output, but since this class can be called again and again, it should still be in there. If you have more than one row, a sticky="e"
for a Label widget would mean to align it to the right, example:
In words
Being new to tkinter and its wording (widgets, pack, grid, frame and so on), here is an overview of what this is all about.
The steps to get rid of the error are roughly:
- Comment out all of the
.pack()
commands. The error will be gone, and it will only show the widgets that are left over that are published with the .grid()
command.
- Check your GUI: wherever you want to have more than one widget in one row (that is, having two or more columns), you need to put it into the right columns with the
.grid()
command. For example if you want to have a label left to an entry widget on the right, the label must be in column 0 and the entry field in column 1. And for this to work, the frame that holds these two widgets needs to offer these two columns (or you do not put it into a frame at all, then the default window can grow as big as you like, see Python tkinter how to use grid sticky, also for .grid_columnconfigure()
as a way to change these columns. Put the max column number in the grid of the root's frame or the root window, but you put the Entry widget into the root window but the Label into the frame.
- As a beginner, you will normally just have the "root" window and at the most one frame for it to make the grid, which is nothing but the whole window of the app as a grid. This is what your code in question asks for, and you should not even need a Frame then. For another example with a Frame, check again How does the sticky command affect the python code in Tkinter?.
- If you have child frames as well, a window inside the window so to speak, then you need to understand nested frames (parent/child/grandchild... frames) and try to decide for each frame whether packing everything in a row is enough or whether you want to have widgets next to each other in a grid. A code example is at tkinter gui layout using frames and grid.
Wrap up
.grid
needs to take over anything were .pack()
was before as soon as you want columns next to each other since .pack()
packs it all just in a row below each other in the order of the coding, see The Packer. Just replace the old .pack()
lines with .grid(column=?)
lines and add a Frame with the needed number of columns as well into which you can put the widgets, or drop the Frame and take the default root window for the grid.
Main tkinter guide
tkinter — Python interface to Tcl/Tk
frame
, rather thatroot
. – Antibiotic