简体   繁体   中英

Tkinter “place” geometry manager not working

I've been learning Python from an e-book. Right now I am learning about the Tkinter module

The book suggested running the following code. However, it does not work as it should. Any ideas why?

from Tkinter import *

window = Tk()
window.geometry("200x200")

my_frame = Frame()
my_frame.pack

button1 = Button(my_frame, text = "I am at (100x150)")
button1.place(x=100, y=150)

button2 = Button(my_frame, text = "I am at (0 x 0)")
button2.place(x=0, y=0, width=100, height=50)

window.mainloop()

What I should get:

理想的结果

What I get:

实际结果

After adding button1.pack() and button2.pack() , I get this:

使用不同几何图形管理器的结果

  1. don't use place . Learn to use pack or grid . Widgets managed by place won't affect the size of their containing parent. Because you don't give my_frame a size and because you don't pack it so that it fills the window, it's only 1 pixel tall by one pixel wide. This makes it (and the widgets inside it) effectively invisible. If you insist on using place , you need to either give my_frame a size, or pack it with options that cause it to fill its parent.
  2. my_frame.pack should be my_frame.pack() (note the trailing parenthesis)

If you're more interested in a quick fix rather than an explanation, pack my_frame like this:

my_frame.pack(fill="both", expand=True)

That's all you need to fix your code.

The smallest change I could make to make your code work is like so:

If you are going to use the Frame, you need to give it a size like so:

from Tkinter import *

window = Tk()
window.geometry("300x300")

# Note the change to this line
my_frame = Frame(window, width=300, height=300) 
my_frame.pack() # Note the parentheses added here

button1 = Button(my_frame, text="I am at (100x150)")
button1.place(x=100, y=150)

button2 = Button(my_frame, text="I am at (0 x 0)")
button2.place(x=0, y=0, width=100, height=50)

window.mainloop()

Also, the pack() must be a function call, so add parentheses

You forgot to call the myframe.pack function - you just put the function name there, which is valid statement, but the frame was not "packed" into the window (I also added fill and expand to make the frame fill the whole window, otherwise placing wouldn't work). This should work:

from Tkinter import *

window = Tk()
window.geometry("200x200")

my_frame = Frame(window)
my_frame.pack(fill=BOTH, expand=True)

button1 = Button(my_frame, text = "I am at (100x150)")
button1.place(x=100, y=150)

button2 = Button(my_frame, text = "I am at (0 x 0)")
button2.place(x=0, y=0, width=100, height=50)

window.mainloop()

The problem seems to be that you are using pack on your frame, and place on the widgets. You should not mix Tkinter layout managers; use either pack , or grid , or place .

If you use place for your widgets, then frame.pack does not know how large to make the frame. You have to manually provide the size of the frame to fit all its widgets, either by using the width and height parameters in the constructor, or by using frame.place , eg

root = Tk()
root.geometry("300x300")

frame = Frame(root)
frame.place(width=200, height=200)

button1 = Button(frame, text = "I am at (100x150)")
button1.place(x=100, y=150)

button2 = Button(frame, text = "I am at (0 x 0)")
button2.place(x=0, y=0, width=100, height=50)

root.mainloop()

But as others have already noted, I would not use place at all and instead rather switch to grid or pack . This way, the frame's size will automatically adapt to fit all its contents.

Your buttons were placed in inside the Frame my_frame , but the frame itself did not appear on the screen because of the missing parentheses after my_frame.pack . Also, the size of the frame itself should be indicated in the parentheses and be big enough to contain the buttons

In addition, you can't use place for one widget and pack for another, the placement system has to be consistent throughout your code. Here is the code edited to work:

from Tkinter import *

window = Tk()
window.geometry("200x200")

my_frame = Frame(window)
my_frame.place(x=0, y=0, width=200, height=200)

button1 = Button(my_frame, text = "I am at (100x150)")
button1.place(x=100, y=150, width=100, height=50)

button2 = Button(my_frame, text = "I am at (0 x 0)")
button2.place(x=0, y=0, width=100, height=50)

window.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM