Python Forum

Full Version: Using place for a button, many examples but AttributeError, tkinter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
This must be very simple, how to Place a button by x and y coordinates, not using a frame/grid.

button.place(x=100, y=200)
Shown in examples not working (for me).

My test code:
from tkinter import *
from tkinter import messagebox, ttk

root = Tk() 
root.title("  Place button  ")
root.geometry( "300x300" ) #(HxV)

label = Label( root , text = " " ) 
label.pack()

label1 = Label( root , text = "Set Value " ) 
label1.place(x=35, y=140)

combo = ttk.Combobox(values=["300","250","225","200","175","150","140","130","125"])
combo.bind("<<ComboboxSelected>>")
#combo.pack(padx=10,pady=10)
combo.place(x=100, y=140)

button = Button( root , text = "Save changes").pack() 
#button.place(x=100, y=200)  #AttributeError: 'NoneType' object has no attribute 'place'

root.mainloop()
I found this:
Quote:Don't mix layout managers (pack, grid, place) on the same parent widget. If you use pack or grid on a widget that contains the button, place might not work as expected.
Really vague, so place works with some widgets and not others...
from tkinter import *
from tkinter import messagebox, ttk

root = Tk()
root.title("  Place button  ")
root.geometry( "300x300" ) #(HxV)

label = Label( root , text = " " )
label.pack()

label1 = Label( root , text = "Set Value " )
label1.place(x=35, y=140)

combo = ttk.Combobox(values=["300","250","225","200","175","150","140","130","125"])
combo.bind("<<ComboboxSelected>>")
#combo.pack(padx=10,pady=10)
combo.place(x=100, y=140)

button = Button( root , text = "Save changes")
button.place(x=100, y=200)  #AttributeError: 'NoneType' object has no attribute 'place'

root.mainloop()
Botton(...) returns a Button instance and the method pack() on this instance returns None, not the Button. You're assigning None to button. Also, you can use only one system to place the objects: pack, grid and place. They are mutually exclusive.

Additionally, star imports are bad.
Improved version without star imports and used a code formatter (ruff format).
from tkinter import Tk, Label, Button
from tkinter import ttk

root = Tk()
root.title("  Place button  ")
root.geometry("300x300")  # (HxV)

label = Label(root, text=" ")
label.pack()

label1 = Label(root, text="Set Value ")
label1.place(x=35, y=140)

combo = ttk.Combobox(
    values=["300", "250", "225", "200", "175", "150", "140", "130", "125"]
)
combo.bind("<<ComboboxSelected>>")
combo.place(x=100, y=140)

button = Button(root, text="Save changes")
button.place(x=100, y=200)

root.mainloop()
Thanks DE

Oh yes, the .pack() at the end of the button line caused this.
will loose the *
What is the purpose of bind?
combo = ttk.Combobox(values=["300","250","225","200","175","150","140","130","125"])
combo.bind("<<ComboboxSelected>>")
This makes sense because it binds a function to be called when a combobox item is seleted.
combo = ttk.Combobox(values=["300","250","225","200","175","150","140","130","125"])
combo.bind("<<ComboboxSelected>>", some_function)
I avoid using place(). I use grid() or pack() instead. Using a geometry manager is much quicker (once you learn how to use them) and you don't have to worry about things like changing font size messing up your layout. Eventually you will want to support styling, and that pretty much eliminates the option of using place() to position the widgets.