Oliver
Oliver

Reputation: 831

Python Tkinter buttons are very far apart

I have been learning some python and I have started developing an app, which will allow the user to make some art using a GUI and a Canvas within a Tkinter window, using Tkinter buttons and fields. buttons are very far apart

However, for some reason all these buttons are very far apart and I'm not quite sure by what logic their exact position is determined. Here is my code, which sets up the window and the buttons:

area = Canvas(self)
area.grid(row = 1, column=0, columnspan=2, rowspan=28, padx=5, sticky = E+W+S+N)
#columns
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
#Background Colour 
colourL = Label(self, text="Background colour:")
colourL.grid(row=1, column=3)
colourbg = Entry(self)
colourbg.grid(row = 1, column=4)
#Turtle Colour
turtcL = Label(self, text="Turtle colour:")
turtcL.grid(row=2, column=3)
turtcol = Entry(self)
turtcol.grid(row = 2, column=4)
setCol=Button(self, text="Set colours",command=lambda: setColour(alex,turtcol.get(),area,colourbg.get()) )
setCol.grid(row=2, column=5)
#Fractal Button
fractalL = Label(self, text="Order of Fractal:")
fractalL.grid(row=5, column=4)
fractorder = Entry(self)
fractorder.grid(row = 6, column=4)
#Buttons
drawButton = Button(self, text="Draw", command=lambda: draw(100, turtles, 80))
drawButton.grid(row=3, column=3)

I would be very grateful if someone could tell my why and how to make the buttons and fields be closer together.

Upvotes: 1

Views: 1492

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386362

There's not enough code in your question to say for certain what is going on. My guess is is that row 3 is being given a bigger weight than the other rows.

However, instead of chasing the bug, I recommend two modifications to how you are going about creating your GUI.

First, instead of trying to put everything into a single grid, divide your GUI in half. One half has a canvas and nothing else, the other half has a bunch of buttons. For me, the natural organization is to start by creating a frame to contain the buttons. Then, use pack to put the canvas on the left and the frame on the right.

Once you have that working, you can organize your buttons without having to worry about interactions between the button grid and the canvas.

Second, put all of your calls to grid together, so you can more easily visualize everything at once.

It would look something like the following. Notice that all of the buttons use control as their parent. Also, entry widgets use the sticky option to fill the space they've been given. You can do the same with buttons if you want them to all be a uniform size. You can also use the sticky attribute to line up your labels either to the left or right, depending on how you want the GUI to look.

...
# create the two sides:
area = Canvas(self)
controls = Frame(self)

area.pack(side="left", fill="both", expand=True)
controls.pack(side="right", fill="both", expand=False)

# create the buttons and labels
colourL = Label(controls, text="Background colour:")
colorbg = Entry(controls)

turtcL  = Label(controls, text="Turtle colour:")
turtcol = Entry(controls)
setCol  = Button(controls, text="Set colours",command=lambda:      

fractalL = Label(controls, text="Order of Fractal:")
fractorder = Entry(controls)

drawButton = Button(controls, text="Draw", command=lambda: draw(100, turtles, 80))

# now, arrange them on the screen
colourL.grid(row=1, column=1)
colourbg.grid(row=1, column=2, sticky="ew"
turtcL.grid(row=2, column=1)
turtcol.grid(row=2, column=2, sticky="ew")
setCol.grid(row=2, column=3)
drawButton.grid(row=3, column=1)
fractalL.grid(row=5, column=2)
fractorder.grid(row=6, column=2, sticky="ew")
...

Finally, when using grid, you should always give at least one column and one row a positive "weight". This tells tkinter where to give any extra space after placing the widgets in their place.

Assuming that you want all of the buttons to be at the top, you can give row 7 (the row after the last row of widgets) a positive weight. Also, assuming you want the column that contains entries to be as wide as possible, you can give column 2 a weight:

controls.grid_rowconfigure(7, weight=1)
controls.grid_columnconfigure(2, weight=1)

Upvotes: 2

Related Questions