3
votes

I am trying to set the width of some canvas to the width of master (fullscreen) and the height to 1/5, 3/10 and 1/2 of master. Window is correctly shown, but canvas doesn't appear. I unsuccessfully tried place() instead of pack() with relwidth = 1 and relheight = 0.2. I just want my three canvas stacked and horizontally filling the window.

master = Tk()
master.attributes('-zoomed', True)

w = master.winfo_width()
h = master.winfo_height()
hu = int(h/10)
h1 = hu*2
h2 = hu*3
h3 = hu*5

c1 = Canvas(master, bg='grey', width = w, height = h1)
c1.pack()
c2 = Canvas(master, bg='blue', width = w, height = h2)
c2.pack()
c3 = Canvas(master, bg='red', width = w, height = h3)
c3.pack()

Edit: my working code is now:

c1 = Canvas(master)
c1.place(rely = 0, relheight = 0.2, relwidth = 1)
c2 = Canvas(master)
c2.place(rely = 0.2, relheight = 0.3, relwidth = 1)
c3 = Canvas(master)
c3.place(rely = 0.5, relheight = 0.5, relwidth = 1)

but I am having a side effect, I can't align at the center a text:

c1.create_text(0, 0, text = 'text', fill = 'red', font = ('olivier', 30, 'bold'))
c1.update()

that I solved in this unelegnat way:

master.update_idletasks()
w = master.winfo_width()
h = master.winfo_height()
ww = int(w/2)
hh = int(h/10)
c1.create_text(ww, hh, text = 'text', fill = 'red')
2

2 Answers

3
votes

You need to use the .place() geometry manager.

.place() has two main parameters which I think you will need.

The first one is relheight. True to its name, it sets the height of any widget relative to it's parent widget.

So, if relheight was 0.5, then the height would be 0.5(height), or 50% of the parent widgets height.

The same applies to relwidth, which works the same way but applies to the width instead.

Read more about .place() here.

Also, if you want your code:

master = Tk()
master.attributes('-zoomed', True)

c1 = Canvas(master, bg='grey')
c1.place(x = 0, rely = 0, relheight = 0.2, relwidth = 1)
c2 = Canvas(master, bg='blue')
c2.pack(x = 0, rely = 0.25, relheight = 0.3, relwidth = 1)
c3 = Canvas(master, bg='red')
c3.pack(x = 0, rely = 0.5, relheight = 0.5, relwidth = 1)

Hope this helps!

Edit: .place() doesn't work for canvas elements. For that, you need to take the legnth and width of the canvas, and then divide both by two(if you want the middle).

For example:

height = 100
width = 100
c = Canvas(master, bg = "blue", height = height, width = width, highlighthickness = 0)
c.place(x = 0, rely = 0.5, relheight = 0.2, relwidth = 1)
text = c.create_text(height/2, width/2, text = "text")

This will place the text text in the center of your canvas.

Hope this helps!

2
votes

At the first time you use master.winfo_width() and master.winfo_height(),it will be zero.(If you use print(w,h),you will find all of them are zero.)

Just add master.update_idletasks() before master.winfo_xxxx.

All the code could be:

from tkinter import *
master = Tk()
master.state('zoomed')

# add here 
master.update_idletasks()
w = master.winfo_width()
h = master.winfo_height()
hu = int(h/10)
h1 = hu*2
h2 = hu*3
h3 = hu*5

c1 = Canvas(master, bg='grey', width = w, height = h1)
c1.pack()
c2 = Canvas(master, bg='blue', width = w, height = h2)
c2.pack()
c3 = Canvas(master, bg='red', width = w, height = h3)
c3.pack()
master.mainloop()