Search code examples
pythontkinter

TKINTER frame geometry


I want to be able to specify different dimensions for each frame, As I did so with the root frame (App()). I'm not sure how to go about this as I cannot specifically add a new geometry each frame class (Or I don't know how). And also I believe I need to expand my frames as currently when I open the new frame it doesn't match the previous root frames geometry.

import tkinter
import customtkinter as ctk

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")

class App(ctk.CTk):
    def __init__(self):
        ctk.CTk.__init__(self)
        self._frame = None
        self.switch_frame(loginPage)

        self.geometry('450x300')
        self.title('Login Required')
        self.Frame = loginPage(self)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class loginPage(ctk.CTkFrame):
    def __init__(self, master):
        ctk.CTkFrame.__init__(self, master)
        ctk.CTkButton(self, text="Open new window",
                      command=lambda: master.switch_frame(pageTwo)).pack()

class pageTwo(ctk.CTkFrame):
    def __init__(self, master):
        ctk.CTkFrame.__init__(self, master)



if __name__ == "__main__":
    app = App()
    app.mainloop()

I tried to manually swap the frame geometry with the same method as in the root frame but would not work.


Solution

  • ngl I have never seen py-tkinker structured like this yet never-the-less here is and example of code you can use. hope it helps

    import tkinter
    import customtkinter as ctk
    
    ctk.set_appearance_mode("dark")
    ctk.set_default_color_theme("blue")
    
    class App(ctk.CTk):
        def __init__(self):
            ctk.CTk.__init__(self)
            self._frame = None
            self.switch_frame(loginPage, None)
    
            self.geometry('450x300')
            self.title('Login Required')
            self.Frame = loginPage(self)
    
        def switch_frame(self, frame_class, size):
            if self._frame is not None:
                self._frame.destroy()
            self._frame = frame_class(self)
    
            if size is not None:
                self._frame.configure(width=size[0], height=size[1])
            self._frame.pack()
    
    class loginPage(ctk.CTkFrame):
        def __init__(self, master):
            FrameSize = [500,800] # <--- You can change the [X,Y] Geometry here
            ctk.CTkFrame.__init__(self, master)
            ctk.CTkButton(self, text="Open new window", command = lambda size = FrameSize: master.switch_frame(pageTwo, size)).pack()
    
    class pageTwo(ctk.CTkFrame):
        def __init__(self, master):
            ctk.CTkFrame.__init__(self, master)
    
    if __name__ == "__main__":
        App().mainloop()
    

    and if you really wanted it to be like how you define the geometry you can do something like:

    string_ = '0000x000'
    list_ = s.split('x')
    

    How I would code it:

    from tkinter import *
    from tkinter.font import BOLD
    # using the '*' wildcard is not the most optimized but the easiest
    # it imports everything from tkinter yet most you don't need
    import customtkinter as ctk
    
    ctk.set_appearance_mode("dark")
    ctk.set_default_color_theme("blue")
    
    class App():
        def __init__(self, master):
            self = master
            self.geometry('450x300+300+300')
            self.title('Login Required')
            
            App.addWindowButton(self, [500,800])
            
        def addWindowButton(self, FrameSize):
            newWindowButton = ctk.CTkButton(self, text="Open new a window")
            newWindowButton.pack(pady=10, ipady=2)
            # you can confiure objects after placing them and pass the object it's self
            # in this example you can destroy the button
            newWindowButton.configure(command = lambda self=self, size = FrameSize, button=newWindowButton: loginPage.switch_frame(self, size, button))
    
    class loginPage:
        '''A class to hold all the LoginPage Functions'''
            
        def switch_frame(self, size, newWindowButton):
            '''Switch to the login frame \n
            You can see this note whenever you hover over the function'''
            
            newWindowButton.destroy()
            
            # creates frame object
            frame_ = ctk.CTkFrame(self, bg_color="#151515")
            frame_.configure(width=size[0], height=size[1])
            #frame_.pack(fill=BOTH, expand=True), use this to have the frame fill the window
            frame_.pack(pady=20)
            # you need this so the frame does not resize to conform to a child-object 
            frame_.pack_propagate(False)
            
            # adds the 'Login Window' text
            ctk.CTkLabel(frame_, text="Login Window", font=('Candara', 23, BOLD)).pack(pady=(30,0))
    
    if __name__ == "__main__":
        root = ctk.CTk()
        App(root)
        root.mainloop()