Reputation: 257
The print output of my code is,
master.winfo_width:300,winfo_height:300
frame.winfo_width:300,winfo_height:269
why is frame.winfo_height()
269 rather than 300?
Environment: Windows 10 Home 64 bit edition, python 3.7.4, tkinter verion 8.4
import tkinter as tk
from PIL import Image, ImageTk
class MyFrame(tk.Frame, object):
def __init__(self, master=None, width=10, height=10):
super(MyFrame, self).__init__(master)
self.bind_all('<Key>', self.keyevt)
def keyevt(self, evt):
print("self.winfo_width:%d,winfo_height:%d"%(self.winfo_width(),self.winfo_height()))
master = tk.Tk()
master.resizable(False, False)
master.geometry("300x300")
lander = ImageTk.PhotoImage(file="./csdn.png")
frame = MyFrame(master, width=300, height=300)
master.update()
canvas = tk.Canvas(frame)
canvas.pack()
frame.pack()
frame.update()
imagelander = canvas.create_image(150, 150, image=lander)
canvas.pack()
print("master.winfo_width:%d,winfo_height:%d"%(master.winfo_width(),master.winfo_height()))
print("frame.winfo_width:%d,winfo_height:%d"%(frame.winfo_width(),frame.winfo_height()))
master.mainloop()
Upvotes: 0
Views: 1964
Reputation: 142691
Frame
changes size to fit to size of its childrens.
Because Canvas
has default height 267
so automatically Frame
has the same size. If you set
canvas = tk.Canvas(frame, height=300)
then Frame
will have height 300
too.
You can also turn off this and frame will not change its size
frame.propagate(False)
If you will need to resize Frame
when window change size then more useful can be
frame.pack(expand=True, fill='both')
BTW: To set size in your own frame you have to send size to `super()
super().__init__(master, width=width, height=height) # , bg='red')
Example code.
I added background colors to see size of Canvas (green) and Frame (red).
I also removed image so everyone can easily copy code and run it.
import tkinter as tk
class MyFrame(tk.Frame):
def __init__(self, master=None, width=10, height=10):
super().__init__(master, width=width, height=height, bg='red')
self.bind_all('<Key>', self.keyevt)
def keyevt(self, evt):
print("self.winfo_width:%d,winfo_height:%d"%(self.winfo_width(),self.winfo_height()))
def test(event=True):
print("master: {}, {}".format(master.winfo_width(), master.winfo_height()))
print("frame : {}, {}".format(frame.winfo_width(), frame.winfo_height()))
print("canvas: {}, {}".format(canvas.winfo_width(), canvas.winfo_height()))
master = tk.Tk()
master.resizable(False, False)
master.geometry("300x300")
frame = MyFrame(master, width=300, height=300)
frame.propagate(False)
frame.pack()#expand=True, fill='both')
canvas = tk.Canvas(frame, bg='green')#, height=300)
canvas.pack()
print('before update')
test()
master.update()
print('after update')
test()
print('200 ms after starting mainloop')
master.after(200, test)
#print('when window change size')
#master.bind('<Configure>', test)
master.mainloop()
Upvotes: 3