Stefan Saran
Stefan Saran

Reputation: 87

widget is being recognized as a frame when using place on a different widget python 3 tkinter

im trying to make an application that can go to different frames but i ran into a problem that seems basic, but its new to me and dont know how to fix it. how do i move widgets on a frame using place? when i try to use this code on about_btn:

self.about_btn.place(rely=0.5)

then the start button is covered the half by the about button, i want to know why is it doing this and how do i fix it? using higher rely value button will go covered by different frame. i want to move widgets frely using place and moving them on the specific frame. Any help and suggestions or improvement for code will be very helpful, here is my example code:

import tkinter as tk
from tkinter import *


class App():
    def __init__(self, parent):
        self.app = parent
        self.app.geometry("300x300")
        self.app.title("test application")

        self.home_frame = tk.Frame(self.app)
        self.category_frame = tk.Frame(self.app)
        self.home_frame.pack()

        self.start_btn = tk.Button(self.home_frame, text="Start")
        self.start_btn.pack()

        self.about_btn = tk.Button(self.home_frame, text="About")
        self.about_btn.place(rely=0.5)

if __name__ == "__main__":
    app1 = tk.Tk()
    App_class = App(app1)
    app1.resizable(False, False)
    app1.mainloop()

Upvotes: 1

Views: 105

Answers (1)

patthoyts
patthoyts

Reputation: 33223

Do not mix geometry management algorithms within a container. You are using pack for start_btn and place for about_btn both in the home_frame container. Pick one - ideally either grid or pack. Place is not usually sensible.

For example, to pack your buttons on a row at the top and right:

self.home_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.about_btn.pack(side=tk.RIGHT, anchor=tk.NE)
self.start_btn.pack(side=tk.RIGHT, anchor=tk.NE)

Using place instead:

self.home_frame.place(relwidth=1.0, relheight=1.0)
self.start_btn.place(relx=0.5, rely=0, relwidth=0.25)
self.about_btn.place(relx=0.75, rely=0, relwidth=0.25)

Frankly, learn to use grid. It will be worth it. Here is a reworked version that illustrates all three geometry managers for two buttons.

import tkinter as tk

class App():
    def __init__(self, parent):
        self.app = parent
        self.app.geometry("300x300")
        self.app.title("test application")

        f1 = tk.Frame(self.app, relief=tk.GROOVE, borderwidth=2)
        b1a = tk.Button(f1, text="Place A")
        b1b = tk.Button(f1, text="Place B")
        b1a.place(relx=0.5, rely=0, relwidth=0.25)
        b1b.place(relx=0.75, rely=0, relwidth=0.25)

        f2 = tk.Frame(self.app, relief=tk.GROOVE, borderwidth=2)
        b2a = tk.Button(f2, text="Two A")
        b2b = tk.Button(f2, text="Two B")
        b2b.pack(side=tk.RIGHT, anchor=tk.NE)
        b2a.pack(side=tk.RIGHT, anchor=tk.NE)

        f3 = tk.Frame(self.app, relief=tk.GROOVE, borderwidth=2)
        b3a = tk.Button(f3, text="Grid A")
        b3b = tk.Button(f3, text="Grid B")
        b3a.grid(row=0, column=0, sticky=tk.NE)
        b3b.grid(row=0, column=1, sticky=tk.NE)
        f3.grid_rowconfigure(0, weight=1)
        f3.grid_columnconfigure(0, weight=1)

        f1.grid(row=0, column=0, sticky=tk.NSEW)
        f2.grid(row=1, column=0, sticky=tk.NSEW)
        f3.grid(row=2, column=0, sticky=tk.NSEW)

        for row in range(0,3):
            parent.grid_rowconfigure(row, weight=1)
        parent.grid_columnconfigure(0, weight=1)


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    #app1.resizable(False, False)
    root.mainloop()

Upvotes: 1

Related Questions