Button Layout with Tkinter?

Button Layout with Tkinter?



I want to make my buttons a 2 x 2 grid on the bottom of the window with a canvas above them but the buttons always seem to stack weird when I use .pack(side = whatever).



A major thing I also want the buttons and canvas to have relative size i.e. % so that whenever the window is resized the buttons still make up the right area.



I am not sure how to do this being new to tkinter and any help is appreciated.


import tkinter
from tkinter import *

code = Tk()

def LAttack():
print(something);
def HAttack():
print(something);
def FField():
print(something);
def Heal():
print(something);
def Restart():
print(something);

Attack1 = tkinter.Button(code,text = ("Light Attack"), command = LAttack)
Attack1.pack(side = LEFT)
Attack2 = tkinter.Button(code,text = ("Heavy Attack"), command = HAttack)
Attack2.pack(side = RIGHT)
Defense1 = tkinter.Button(code,text = ("Forcefield"), command = FField)
Defense1.pack(side = LEFT)
Defense2 = tkinter.Button(code,text = ("Heal"), command = Heal)
Defense2.pack(side = RIGHT)
Restart1 = tkinter.Button(code,text = ("Restart"), command = Restart)
Restart1.pack(side = TOP)

code.mainloop()



But I want it to look like this:
Mock up for GUI






Hi there. Please would you post your code in the question so that others can identify what your problem is. Thanks! Also might help to include an image of your resulting layout.

– feedMe
Sep 13 '18 at 13:32






If you are creating a grid of buttons, have you read up on how to use the grid geometry manager?

– Bryan Oakley
Sep 13 '18 at 14:29


grid




1 Answer
1



I want to make my buttons a 2 x 2 grid on the bottom of the window with a canvas above them but the buttons always seem to stack weird when I use .pack(side = whatever).



To me this means that you clearly have two separate areas to be concerned with: a top area with a canvas, and a bottom area with buttons. The first step is to create those two areas. For the top just use the canvas, and for the bottom use a frame.



I'm going to assume you want the canvas to take up as much space as possible, with the buttons always on the bottom. For that sort of arrangement, pack makes the most sense.


pack



The following gives us a program that has a canvas at the top and a frame at the bottom to hold the buttons. When you resize the window, the button frame remains at the bottom and the canvas fills the rest of the space:


import tkinter as tk

root = tk.Tk()

canvas = tk.Canvas(root, background="white")
button_frame = tk.Frame(root)

button_frame.pack(side="bottom", fill="x", expand=False)
canvas.pack(side="top", fill="both", expand=True)

# <button code will be added here...>

root.mainloop()



Now we can focus on the buttons. You want the buttons in a 2x2 grid (though you have 5 buttons...?), so the natural choice is to use grid rather than pack. We want these buttons to be in the bottom frame, so we give that frame as the parent or master of the buttons.


grid


pack



You also somewhat curiously wrote "whenever the window is resized the buttons still make up the right area" even though earlier you said you wanted them on the bottom. I'm going to assume you mean that you want them in the bottom-right corner.



To accomplish this, we are going to create a grid with two rows and three columns. The column on the left will be empty, and it will take up any extra space to force the buttons to be on the right (of course, you can put things in this column if you wish)



This creates four buttons:


attack1 = tk.Button(button_frame, text="Light Attack")
attack2 = tk.Button(button_frame, text="Heavy Attack")
defense1 = tk.Button(button_frame, text="Forcefield")
defense2 = tk.Button(button_frame, text="Heal")



... this causes the first column to expand to fill any extra space:


button_frame.grid_columnconfigure(0, weight=1)



... and this lays them out in a grid (it's always good to separate widget creation from widget layout, because it makes it easier to visualize the layout in the code)


attack1.grid(row=0, column=1, sticky="ew")
attack2.grid(row=0, column=2, sticky="ew")
defense1.grid(row=1, column=1, sticky="ew")
defense2.grid(row=1, column=2, sticky="ew")



The end result is this:



screenshot



When resized, the buttons retain their relative position:



screenshot after resizing



The point of this is to show that you need to spend a few minutes organizing the items on the screen into logical groups. There are different layout tools for solving different problems (grid, pack, place), and most windows will benefit from using the right tool for each type of layout problem you're trying to solve (pack is good for horizontal and vertical layouts, grid is good for grids, and place covers a few edge cases where pixel-perfect control is needed).


grid


pack


place


pack


grid


place






This looks great but a few questions. Could I make the frame change size relative to window so when it gets bigger the frame gets bigger. And 2 can you make the buttons fill up 50% of the frame width wise. Thanks.

– Roberto Chavo
Sep 13 '18 at 21:58






@RobertoChavo: that's exactly what the code does, and the screenshots show it. The frame automatically got widget when I resized the windows. And yes, you can make the buttons fill up 50% of the screen. There are plenty of options to do what you want.

– Bryan Oakley
Sep 13 '18 at 22:33






so I could make it look like my mock up that I posted?

– Roberto Chavo
Sep 14 '18 at 13:45







@RobertoChavo: yes, of course. Tkinter's geometry managers are very powerful. There's probably no design you could come up with that you can't do with some combination of pack, place, and/or grid.

– Bryan Oakley
Sep 14 '18 at 14:07


pack


place


grid






I really can't figure out how. I change the column span to make the buttons bigger but they don't change size. I change the columns and rows and the buttons don't move.

– Roberto Chavo
Sep 16 '18 at 22:23



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)