0

I would like to position my title at the center of the window but it seems affect by the pack() method of the button located at the bottom of the screen. enter image description here

I remove the button at the bottom then the label is centralized. May I know how should i modify the code ?

# Import any required modules or libraries
from datetime import datetime
import tkinter as tk

class Window:
    def __init__(self, root):
        self.root = root
        self.root.title("Software Title")
        
        # Set window attributes
        self.root.attributes("-fullscreen", True)

        # Create a container frame
        self.container = tk.Frame(self.root)
        self.container.pack()

        # Create buttons to switch between pages
        self.button_home = tk.Button(self.root, text="Home",height= 3, width=13, command=self.show_home_page)
        self.button_home.pack(side="left", anchor= "sw")
        
        self.button_about = tk.Button(self.root, text="Page 2",height= 3, width=13, command=self.show_about_page)
        self.button_about.pack(side="left", anchor= "sw")

        self.button_contact = tk.Button(self.root, text="Page 3",height= 3, width=13, command=self.show_contact_page)
        self.button_contact.pack(side="left", anchor= "sw")

        # Create close button
        self.close_button = tk.Button(self.root, text="Close",height= 3, width=13, command=self.close_window)
        self.close_button.pack(side="right", anchor= "se")

        # Create page frames
        self.home_page_frame = tk.Frame(self.root)
        self.about_page_frame = tk.Frame(self.root)
        self.contact_page_frame = tk.Frame(self.root)

         # Create labels within each page
        self.home_page_label = tk.Label(self.home_page_frame, text="Main Page")
        self.about_page_label = tk.Label(self.about_page_frame, text="Second Page")
        self.contact_page_label = tk.Label(self.contact_page_frame, text="Third Page")


        # Create buttons within each page
        self.home_page_buttons = []
        self.about_page_buttons = []
        self.contact_page_buttons = []

        # Page 1 content
        home_page_button = tk.Button(self.home_page_frame, text="Home Page Button {i+1}")
        self.home_page_buttons.append(home_page_button)

        # Page 2 content
        about_page_button = tk.Button(self.about_page_frame, text="About Page Button {i+1}")
        self.about_page_buttons.append(about_page_button)
        
        # Page 3 content
        contact_page_button = tk.Button(self.contact_page_frame, text="Contact Page Button {i+1}")
        self.contact_page_buttons.append(contact_page_button)


        # Show the home page initially
        self.show_home_page()

    def close_window(self):
        self.root.destroy()
    
    def show_home_page(self):
        # Hide other pages
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()

        # Show the home page
        self.home_page_frame.pack()

        # Show the home page label
        self.home_page_label.pack()
        

        # Show the home page buttons
        #for button in self.home_page_buttons:
        #    button.pack()

        

    def show_about_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()

        # Show the about page
        self.about_page_frame.pack()

        # Show the about page label
        self.about_page_label.pack()
        

        # Show the about page buttons
        #for button in self.about_page_buttons:
        #    button.pack()

        # Hide the navigation buttons
        #self.hide_navigation_buttons()

    def show_contact_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.about_page_frame.pack_forget()

        # Show the contact page
        self.contact_page_frame.pack()

         # Show the contact page label
        self.contact_page_label.pack()

        # Show the contact page buttons
        #for button in self.contact_page_buttons:
        #    button.pack()

        # Hide the navigation buttons
        #self.hide_navigation_buttons()

    def hide_navigation_buttons(self):
        # Hide the navigation buttons
        self.button_home.pack_forget()
        self.button_about.pack_forget()
        self.button_contact.pack_forget()

    # Other methods...

# Create the main window
root = tk.Tk()

# Create an instance of the Window class
window = Window(root)

# Run the main event loop
root.mainloop()

After modification, the buttons sticks at one side even i pack the close_button button to right. enter image description here

Code as below:

import tkinter as tk

class Window:
    def __init__(self, root):
        self.root = root
        self.root.title("Software Title")
        self.root.attributes("-fullscreen", True)

        # Create page frames
        self.navigator_frame = tk.Frame(self.root)
        self.navigator_frame.pack(side='bottom',anchor='sw')
        
        self.home_page_frame = tk.Frame(self.root, bg='wheat')
        self.about_page_frame = tk.Frame(self.root, bg='tan')
        self.contact_page_frame = tk.Frame(self.root, bg='tomato')

        # Create buttons to switch between pages
        self.button_home = tk.Button(self.navigator_frame, text="Home",height= 3, width=13,
                                     command=self.show_home_page)
        self.button_home.pack(side="left")
        self.button_about = tk.Button(self.navigator_frame, text="Page 2",height= 3, width=13,
                                      command=self.show_about_page)
        self.button_about.pack(side="left")
        self.button_contact = tk.Button(self.navigator_frame, text="Page 3",height= 3, width=13,
                                        command=self.show_contact_page)
        self.button_contact.pack(side="left")

        # Create close button
        self.close_button = tk.Button(self.navigator_frame, text="Close",height= 3, width=13,
                                      command=self.close_window)
        self.close_button.pack(side="right")
        

         # Create labels within each page
        self.home_page_label = tk.Label(self.home_page_frame, text="Main Page")
        self.about_page_label = tk.Label(self.about_page_frame, text="Second Page")
        self.contact_page_label = tk.Label(self.contact_page_frame, text="Third Page")

        # Show the home page initially
        self.show_home_page()

    def show_home_page(self):
        # Hide other pages
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()
        self.home_page_frame.pack(expand=True, fill='both')
        self.home_page_label.pack(expand=True)

    def show_about_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()
        self.about_page_frame.pack(expand=True, fill='both')
        self.about_page_label.pack(expand=True)

    def show_contact_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack(expand=True, fill='both')
        self.contact_page_label.pack(expand=True)

    def close_window(self):
        self.root.destroy()

root = tk.Tk()
window = Window(root)

root.mainloop()

Chun Seong
  • 19
  • 6
  • 1
    Why don't you put those buttons in a frame and pack the frame at the bottom of the window? – acw1668 Jun 18 '23 at 12:02
  • @acw1668 Thanks for your suggestion and it looks pretty nice, but my buttons all pack to one side, i would like one of the button pack to the right side but it doesn't take effect. Any advise ? – Chun Seong Jun 18 '23 at 14:03

4 Answers4

1

A lot of the code you present does not do anything on the GUI. I have stripped down the code in my example to the bare minimum.

I think your problem is that the .pack() method does sometimes give you surprising results.

In my example I have created space for the page frames with .pack(expand=True, fill='both'), and then placed the label in the middle by .pack(expand=True). I have colour-coded the frames to show where they end up.

Have a look at Tkinter pack method confusion which discusses how the packer works.

For a complex GUI layout I would recommend you study the .grid() function which is more readily understood.

Also, for switching between frames in an application you might want to have a look at Switch between two frames in tkinter?

Example code:

import tkinter as tk

class Window:
    def __init__(self, root):
        self.root = root
        self.root.title("Software Title")
        self.root.attributes("-fullscreen", True)

        # Create buttons to switch between pages
        self.button_home = tk.Button(self.root, text="Home",height= 3, width=13,
                                     command=self.show_home_page)
        self.button_home.pack(side="left", anchor= "sw")
        self.button_about = tk.Button(self.root, text="Page 2",height= 3, width=13,
                                      command=self.show_about_page)
        self.button_about.pack(side="left", anchor= "sw")
        self.button_contact = tk.Button(self.root, text="Page 3",height= 3, width=13,
                                        command=self.show_contact_page)
        self.button_contact.pack(side="left", anchor= "sw")

        # Create close button
        self.close_button = tk.Button(self.root, text="Close",height= 3, width=13,
                                      command=self.close_window)
        self.close_button.pack(side="right", anchor= "se")

        # Create page frames
        self.home_page_frame = tk.Frame(self.root, bg='wheat')
        self.about_page_frame = tk.Frame(self.root, bg='tan')
        self.contact_page_frame = tk.Frame(self.root, bg='tomato')

         # Create labels within each page
        self.home_page_label = tk.Label(self.home_page_frame, text="Main Page")
        self.about_page_label = tk.Label(self.about_page_frame, text="Second Page")
        self.contact_page_label = tk.Label(self.contact_page_frame, text="Third Page")

        # Show the home page initially
        self.show_home_page()

    def show_home_page(self):
        # Hide other pages
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()
        self.home_page_frame.pack(expand=True, fill='both')
        self.home_page_label.pack(expand=True)

    def show_about_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()
        self.about_page_frame.pack(expand=True, fill='both')
        self.about_page_label.pack(expand=True)

    def show_contact_page(self):
        # Hide other pages
        self.home_page_frame.pack_forget()
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack(expand=True, fill='both')
        self.contact_page_label.pack(expand=True)

    def close_window(self):
        self.root.destroy()

root = tk.Tk()
window = Window(root)

root.mainloop()

Was this helpful?

figbeam
  • 7,001
  • 2
  • 12
  • 18
  • Thanks for restructure my code into a more simple way. I create another frame to place all the button. But all the button packed to one side. I wish to locate one fo the button to the another side but it doesn't work. Any advice ? – Chun Seong Jun 18 '23 at 14:05
1

For the updated code, if you want the Close at the right side, you need to make the bottom frame to fill the window width by setting fill='x' in self.navigator_frame.pack(...):

self.navigator_frame = tk.Frame(self.root)
self.navigator_frame.pack(side='bottom', fill='x')  # expand the frame horizontally

Result:

enter image description here

acw1668
  • 40,144
  • 5
  • 22
  • 34
0

pack works by filling up one side of the available space. When you pack the button on the left and right it reduces the available space. The only space available to pack after that is the space between the buttons. Since there are more buttons on the left, anything packed at the top will be offset.

The solution is to pack the frame containing the label first, before the other widgets are packed. It appears that you created a container widget explicitly for this purpose, since you create self.container first and don't seem to be using it for any other purpose. However, you aren't putting the other frames in that container.

So, my guess is that the simplest solution is to move the other frames into the container by setting the parent as self.container rather than self.root.

# Create page frames
self.home_page_frame = tk.Frame(self.container)
self.about_page_frame = tk.Frame(self.container)
self.contact_page_frame = tk.Frame(self.container)

If you had other plans for the container frame, then the solution is to create another container frame for these subframes, and pack that before packing the buttons.

For a visual explanation of how the packer works, see my answer to the question Tkinter pack method confusion

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
-1

If I understood your question correctly, update your pack() method arguments as following one:

def show_home_page(self):
        # Hide other pages
        self.about_page_frame.pack_forget()
        self.contact_page_frame.pack_forget()

        # Show the home page
        self.home_page_frame.pack(expand= True, fill = 'both')

        # Show the home page label
        self.home_page_label.pack(expand= True, fill = 'both')
        

        # Show the home page buttons
        #for button in self.home_page_buttons:
        #    button.pack()
F T
  • 72
  • 5