1

I'm new to python and I've problems with the pack manager. My goal is to create to following layout:

BUTTON1 BUTTON2 LABEL1
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->

I tried the following:

BUTTON1.pack(side=tk.TOP, anchor=tk.W)
BUTTON2.pack(side=tk.TOP, anchor=tk.W,padx=5)
LABEL1.pack(side=tk.TOP, anchor=tk.W,padx=5)
CANVAS.pack(side=tk.BOTTOM,fill=tk.BOTH, expand=1)

Give me the following:

BUTTON1
 BUTTON2
 LABEL1
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->
<--------------CANVAS EXPANDED -------------->

This:

BUTTON1.pack(side=tk.LEFT, anchor=tk.N)
BUTTON2.pack(side=tk.LEFT, anchor=tk.N,padx=5)
LABEL1.pack(side=tk.LEFT, anchor=tk.N,padx=5)
CANVAS.pack(side=tk.BOTTOM,fill=tk.BOTH, expand=1)

Give me this:

BUTTON1 BUTTON2 LABEL1 <--------------CANVAS EXPANDED -------------->
                       <--------------CANVAS EXPANDED -------------->
                       <--------------CANVAS EXPANDED -------------->
                       <--------------CANVAS EXPANDED -------------->
                       <--------------CANVAS EXPANDED -------------->

This is close, but still not what I want:

BUTTON1.pack(side=tk.LEFT, anchor=tk.N)
BUTTON2.pack(side=tk.LEFT, anchor=tk.N,padx=5)
LABEL1.pack(side=tk.TOP, anchor=tk.W,padx=5)
CANVAS.pack(side=tk.BOTTOM,fill=tk.BOTH, expand=1)

Gives me this:

BUTTON1 BUTTON2 LABEL1
                <--------------CANVAS EXPANDED -------------->
                <--------------CANVAS EXPANDED -------------->
                <--------------CANVAS EXPANDED -------------->
                <--------------CANVAS EXPANDED -------------->
                <--------------CANVAS EXPANDED -------------->

How to do it?

Xennon
  • 31
  • 4
  • While I'm usually an advocate for using pack, this seems to be a case of you wanting to build a gridlike GUI. Have you considered using the grid function? Is there a reason why it isn't suitable? – Ethan Field Oct 18 '19 at 09:41
  • Hello Ethan, thanks for your answer. I tried it with a grid, but the canvas doesn't expand the way I wish. I also want to order the buttons from the top left to the right and the picture should fit to the whole area, no matter where the buttons at the top are placed. – Xennon Oct 18 '19 at 11:37
  • Grid does have the capabilities to expand widgets in the manner you describe. https://stackoverflow.com/questions/45847313/what-does-weight-do-in-tkinter and https://stackoverflow.com/questions/50158866/what-is-the-difference-between-column-and-columnspan-in-tkinter-python might help. – Ethan Field Oct 18 '19 at 11:51
  • 1
    Thank you, Problem solved. I write my solution down here. – Xennon Oct 18 '19 at 12:32

2 Answers2

1

Solved the problem with Ethan´s hints:

BUTTON1.grid(row=0,column=0,sticky=tk.NSEW)
BUTTON2.grid(row=0,column=1,sticky=tk.NSEW)
LABEL1.grid(row=0,column=2,sticky=tk.NSEW)
CANVAS.grid(row=1,column=0, sticky=tk.NSEW, columnspan=4)
FRAME.grid_columnconfigure(3,weight=1)
FRAME.grid_rowconfigure(1,weight=1)

With this solution, every row and every column, except the position row = 1 and column = 3, will have the size of the widget (default value weight = 0). Column 3 and 1 have both weight = 1. With this setting, this "cell" will expand to the maximum of the frame and with this setting also the CANVAS, because the canvas is using "cell" (1|3).

Ethan Field
  • 4,646
  • 3
  • 22
  • 43
Xennon
  • 31
  • 4
0

You can't do what you want in the way that you want - pack isn't designed to work this way.

The simplest and most straightforward solution is to use a frame for the row with buttons. You can then pack the buttons and label inside that frame from left to right, and then pack the frame at the top with the canvas below it.

The canonical definition for how pack works can be seen in the section The packer algorithm in the official tcl/tk man pages.

Example:

import tkinter as tk

root = tk.Tk()

button_frame = tk.Frame(root)
BUTTON1 = tk.Button(button_frame, text="Button 1")
BUTTON2 = tk.Button(button_frame, text="Button 2")
LABEL1 = tk.Label(button_frame, text="Label 1")
CANVAS = tk.Canvas(root, background="bisque")

BUTTON1.pack(side="left")
BUTTON2.pack(side="left")
LABEL1.pack(side="left")

button_frame.pack(side="top", fill="x")
CANVAS.pack(side="top", fill="both", expand=True)

root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685