ttk Notebook

The ttk Notebook widget is designed to hold multiple “panes” or pages within a single window, each accessible through tabs. You can think of it as similar to the tabs in a web browser, where each tab displays a unique set of content.

This widget is perfect for organizing related content, such as :

  • Settings Pages: Tabs can separate settings into categories like “General,” “Security,” and “Display.”
  • Document or Data Viewers: You can switch between different sections of content.
  • Analysis Tools: Tabs can separate charts or reports, keeping the layout clean and organized.

Setting Up ttk Notebook

Here’s how to set up a simple ttk Notebook widget:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main window
root = tk.Tk()
root.title("My ttk Notebook Example")
root.geometry("400x300")

# Create the notebook
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')  # Makes it resize with the window

root.mainloop()

Output:

Creating and Adding Tabs in ttk Notebook

Now that we’ve set up the ttk Notebook widget, let’s add some tabs to display different sections in the app. Each tab is like a page in the notebook, where you can display unique content.

To add a tab, we use the notebook.add() method. This method takes two main arguments:

  • window: This is the child widget, like a frame, where you’ll place the content for each tab.
  • options: Options like the tab’s title or label.

Here’s an example of how to create two tabs:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main window
root = tk.Tk()
root.title("My ttk Notebook Example")
root.geometry("400x300")

# Create the notebook
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Create frames to hold content for each tab
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add these frames as tabs in the notebook
notebook.add(tab1, text="Tab 1")  # Adding Tab 1 with title
notebook.add(tab2, text="Tab 2")  # Adding Tab 2 with title

root.mainloop()

Output:

Using Tab Identifiers

Sometimes you’ll need to identify a tab to change its content or configuration. There are three common ways to identify tabs:

  1. Position Index: Use an integer (starting from 0 for the first tab) to specify a tab by its position.
  2. Widget Reference: You can refer to the widget (e.g., tab1, tab2) used as the tab’s content to configure it.
  3. Text Label: If you know the title of the tab, you can search for it by text, though this is less common and may require a loop to find the exact tab.

Here’s an example demonstrating these ways.

Example:

import tkinter as tk
from tkinter import ttk

# Create the main window
root = tk.Tk()
root.title("Tab Identifiers Example")
root.geometry("400x300")

# Initialize the ttk Notebook widget
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Create frames for each tab's content
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)
tab3 = ttk.Frame(notebook)

# Add frames as tabs in the notebook with initial titles
notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")
notebook.add(tab3, text="Tab 3")

# === Identifying Tabs by Different Methods ===

# 1. Using Position Index
# Update the title of the first tab (position index 0)
notebook.tab(0, text="Home Tab")

# 2. Using Widget Reference
# Update the title of the second tab using the widget reference `tab2`
notebook.tab(tab2, text="Settings Tab")

# 3. Using Text Label
# Finding and updating a tab by looping through each to match the label
for i in range(notebook.index("end")):  # 'end' gets the count of all tabs
    if notebook.tab(i, "text") == "Tab 3":  # Looking for tab with "Tab 3" title
        notebook.tab(i, text="Profile Tab")

# Run the application
root.mainloop()

Output:

Screenshot of a ttk Notebook GUI application with three tabs. Each tab displays its title: 'Home Tab', 'Settings Tab', and 'Profile Tab'.

Customizing ttk Notebook

Customization helps create a more user-friendly experience, so now let’s customize the appearance and behavior of our ttk Notebook to make it even better.

Cursor and Takefocus

The cursor property changes the mouse pointer’s appearance when hovering over the tabs while setting the takefocus to True allows users to navigate through the tabs using the keyboard. Here’s an example to demonstrate these options.

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("Custom Cursor and Focus Example")
root.geometry("400x300")

# Initialize the notebook widget
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Create frames for tabs
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add tabs to the notebook
notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")

# Configure cursor and focus
notebook.configure(cursor="hand2")  # Change cursor to hand shape
notebook.configure(takefocus=True)  # Allow keyboard navigation

# Add content to the tabs
label1 = ttk.Label(tab1, text="This is the content of Tab 1")
label1.pack(pady=20)

label2 = ttk.Label(tab2, text="This is the content of Tab 2")
label2.pack(pady=20)

# Run the application
root.mainloop()

Output:

Height, Width, and Padding

You can also change the fixed size and spacing of the tabs for a better layout by using the height, width and padding options. Here’s a simple example:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("Tab Height, Width, and Padding Example")
root.geometry("500x400")

# Initialize the notebook widget with specific height and width
notebook = ttk.Notebook(root, height=300, width=400)
notebook.pack()

# Create frames for tabs
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add tabs to the notebook with padding
notebook.add(tab1, text="Tab 1", padding=(20, 10))  # Adds padding to Tab 1
notebook.add(tab2, text="Tab 2", padding=(10, 5))  # Adds padding to Tab 2

# Add content to the tabs
label1 = ttk.Label(tab1, text="This is the content of Tab 1")
label1.pack(pady=20)

label2 = ttk.Label(tab2, text="This is the content of Tab 2")
label2.pack(pady=20)

# Run the application
root.mainloop()

Output:

Screenshot of a ttk Notebook GUI application with two tabs. Tab 1 (labeled 'Tab 1') has more padding around the text compared to Tab 2 (labeled 'Tab 2').

Advanced Tab Options

Ok, now it’s time to explore some advanced options for customizing each tab in our ttk Notebook.

Text and Images

As you know we can use text option to add labels to each tab. But do you know that we can also display images on the Notebook tabs. First, load an image using PhotoImage and then add it to the tab, see the below example.

And one more thing, you can also specify how the text and image should be arranged using the compound option, like showing the image on top or beside the text.

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("ttk Notebook with Text and Images")
root.geometry("400x300")

# Create the ttk Notebook widget
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Load images (make sure to replace with your own image paths)
image1 = tk.PhotoImage(file="pencil-1.png")  # Replace with your image path
image2 = tk.PhotoImage(file="eraser-1.png")  # Replace with your image path

# Create frames for each tab
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add tabs with text and images
notebook.add(tab1, text="Pencil", image=image1, compound="top")  # Image above text
notebook.add(tab2, text="Eraser", image=image2, compound="top")  # Image above text

# Add content to each tab
label1 = ttk.Label(tab1, text="You are using Pencil")
label1.pack(pady=10)

label2 = ttk.Label(tab2, text="Erase your Mistakes")
label2.pack(pady=10)

# Start the Tkinter main loop
root.mainloop()

Output:

Screenshot of a ttk Notebook GUI application with two tabs. The first tab labeled 'Pencil' displays an image of a pencil above the text. The second tab labeled 'Eraser' displays an image of an eraser above the text.

State and Underline

The state option helps you to manage a tab’s interactive states. You can set a tab to be normal (active) or disabled (inactive), which prevents users from clicking on it.

And with the underline option, you can provide keyboard access hints by underlining specific characters in the tab text. Here’s a simple example:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("Tab Height, Width, and Padding Example")
root.geometry("500x400")

# Initialize the notebook widget with specific height and width
notebook = ttk.Notebook(root, height=300, width=400)
notebook.pack()

# Create frames for tabs
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add tabs to the notebook with padding
notebook.add(tab1, text="Tab 1", padding=(20, 10))  # Adds padding to Tab 1
notebook.add(tab2, text="Tab 2", padding=(10, 5))  # Adds padding to Tab 2

# Add content to the tabs
label1 = ttk.Label(tab1, text="This is the content of Tab 1")
label1.pack(pady=20)

label2 = ttk.Label(tab2, text="This is the content of Tab 2")
label2.pack(pady=20)

# Run the application
root.mainloop()

Output:

Methods for Managing Tabs in ttk Notebook

With ttk Notebook, you can dynamically add, remove, hide, and reorder tabs. These features are useful if your application needs to update its layout based on user actions or other conditions.

Adding and Removing Tabs

To add a tab, you use the add() method. This places the new tab at the end by default. You can add any child widget as a tab (like a frame).

For removing a tab completely, you should use the forget() method. This permanently deletes the tab from the notebook.

Now see this simple example:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main window and ttk Notebook
root = tk.Tk()
root.title("Dynamic Tab Management")
root.geometry("500x400")

notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill="both")

# Function to add a new tab
def add_tab():
    # Count current tabs and create a new tab label based on count
    tab_count = len(notebook.tabs())
    new_tab = ttk.Frame(notebook)  # Create a new frame as a tab
    notebook.add(new_tab, text=f"Tab {tab_count + 1}")  # Add the tab with a title

# Function to remove the last tab
def remove_tab():
    # Get the list of tabs
    tabs = notebook.tabs()
    if tabs:
        # Remove the last tab if there is at least one tab
        notebook.forget(tabs[-1])

# Add buttons to add and remove tabs
add_button = ttk.Button(root, text="Add Tab", command=add_tab)
add_button.pack(side="left", padx=10, pady=10)

remove_button = ttk.Button(root, text="Remove Tab", command=remove_tab)
remove_button.pack(side="right", padx=10, pady=10)

root.mainloop()

Output:

Screenshot of a dynamic ttk Notebook tkinter application with buttons for adding and removing tabs. The notebook currently has empty tabs with titles dynamically generated based on their order (e.g., Tab 1, Tab 2, etc.).

Inserting Tabs at Specific Positions

If you want to add a tab in a specific position, use insert(pos, subwindow, options) method, where:

  • pos: Specifies the position index for the new tab.
  • subwindow: The widget that will serve as the tab content.
  • options: Additional options like text for the tab label.

This will let you control where the new tab appears. Here’s a simple example to demonstrate this:

Example:

import tkinter as tk
from tkinter import ttk

# Create the main window
root = tk.Tk()
root.title("Custom Position Tabs in ttk Notebook")
root.geometry("400x300")

# Create the ttk Notebook widget
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill="both")

# Create frames for each tab
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)
tab3 = ttk.Frame(notebook)
tab4 = ttk.Frame(notebook)

# Add the first two tabs in the default order
notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")

# Insert Tab 3 at the first position (index 0)
notebook.insert(0, tab3, text="Inserted Tab 3 at First Position")

# Insert Tab 4 at the second position (index 1)
notebook.insert(1, tab4, text="Inserted Tab 4 at Second Position")

# Add content to the tabs for demonstration
label1 = ttk.Label(tab1, text="This is Tab 1")
label1.pack(pady=20)

label2 = ttk.Label(tab2, text="This is Tab 2")
label2.pack(pady=20)

label3 = ttk.Label(tab3, text="This is Tab 3, inserted at the first position")
label3.pack(pady=20)

label4 = ttk.Label(tab4, text="This is Tab 4, inserted at the second position")
label4.pack(pady=20)

# Run the application
root.mainloop()

Output:

Hiding and Revealing Tabs

Now let’s say you want to temporarily hide a tab without removing it, you can use the hide() method for that. The tab remains in the notebook but is not visible to the user. This is useful for tabs that need to be conditionally shown.

To bring back a hidden tab, use the select() method, which makes the tab visible and switches focus to it.

Example:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Notebook Tab Management")
root.geometry("400x300")

notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Create frames for each tab
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)

# Add the tabs to the notebook
notebook.add(tab1, text="Tab 1")
notebook.add(tab2, text="Tab 2")

# Add content to Tab 1
label1 = ttk.Label(tab1, text="This is Tab 1.")
label1.pack(pady=20)

# Add content to Tab 2
label2 = ttk.Label(tab2, text="This is Tab 2.")
label2.pack(pady=20)

# Function to hide Tab 2
def hide_tab():
    notebook.hide(tab2)  # Hides Tab 2

# Function to reveal Tab 2
def reveal_tab():
    notebook.select(tab2)             # Selects and displays Tab 2

# Buttons to hide and reveal Tab 2
hide_button = ttk.Button(root, text="Hide Tab 2", command=hide_tab)
hide_button.pack(pady=10)

reveal_button = ttk.Button(root, text="Reveal Tab 2", command=reveal_tab)
reveal_button.pack(pady=10)

root.mainloop()

Output:

a tkinter ttk Notebook with two tabs: 'Tab 1' and 'Tab 2'. Buttons below the notebook allow hiding and revealing tabs

Ttk Notebook Virtual Event

When a user clicks on a different tab of a Notebook, its specific event <<NotebookTabChanged>> is triggered. You can bind a function to this event, meaning the function will automatically run every time the tab changes.

This event can be useful if you need to perform specific actions based on the active tab, like updating content, changing settings, or logging activity. Here’s a simple example:

Example:

import tkinter as tk
from tkinter import ttk

# Function to handle tab changes
def on_tab_change(event):
    current_tab_index = notebook.index("current")  # Get the current tab index
    current_tab_name = notebook.tab(current_tab_index, "text")  # Get the current tab name
    label.config(text=f"You are now viewing: {current_tab_name}")  # Update the label

# Create the main window
root = tk.Tk()
root.title("Notebook Tab Change Example")

# Create the notebook
notebook = ttk.Notebook(root)
notebook.pack(expand=True, fill='both')

# Create tabs
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)
notebook.add(tab1, text="Tab 1") 
notebook.add(tab2, text="Tab 2") 

# Create a label to display the current tab
label = tk.Label(root, text="You are now viewing: Tab 1")
label.pack(pady=10)

# Bind the tab change event
notebook.bind("<<NotebookTabChanged>>", on_tab_change)

root.mainloop()

Output:

Style the ttk Notebook

When your application is easy to use and looks good, it leads to higher satisfaction and better usability. So now we are going to learn how to style the ttk Notebook.

But as you know, before diving into the styling options, it’s important to understand the class names associated with the notebook and its tabs.

TNotebookThis is the main class for the notebook widget.
TNotebook.TabThis class name is for individual tabs within the notebook. It controls how each tab looks and behaves.

We will use these class names with the ttk Style() to style the ttk Notebook and its tabs.
When customizing styles, you may add a custom name before these class names (like MyCustom.TNotebook) to differentiate between the default styles and your custom styles.

By doing this, you can apply unique settings without affecting other notebooks in your application.

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("Beautiful Colorful ttk Notebook Example")
root.geometry("800x600")

style = ttk.Style()
style.theme_use("classic") 

# Configure TNotebook
style.configure("FruitNotebook.TNotebook",
                background="yellow", 
                borderwidth=2,
                tabposition='s',  # Positioning tabs at the bottom
                tabmargins=20, padding=20) 

# Configure TNotebook.Tab
style.configure("FruitNotebook.TNotebook.Tab",
                background="orange", 
                foreground="white", 
                padding=(15, 10), 
                font=("Helvetica", 12, "bold"))

# Create a Notebook widget
notebook = ttk.Notebook(root, style="FruitNotebook.TNotebook")
notebook.pack(pady=10, padx=20, expand=True, fill='both')

# Create frames for tabs
frame1 = ttk.Frame(notebook, width=400, height=280)
frame2 = ttk.Frame(notebook, width=400, height=280)
frame3 = ttk.Frame(notebook, width=400, height=280)

# Add frames as tabs
notebook.add(frame1, text='🍏 Apple')
notebook.add(frame2, text='🍌 Banana')
notebook.add(frame3, text='🍒 Cherry')

# Add some content to the tabs
label1 = tk.Label(frame1, text="Welcome to the Apple tab!", font=("Helvetica", 14))
label1.pack(pady=20)

label2 = tk.Label(frame2, text="Welcome to the Banana tab!", font=("Helvetica", 14))
label2.pack(pady=20)

label3 = tk.Label(frame3, text="Welcome to the Cherry tab!", font=("Helvetica", 14))
label3.pack(pady=20)

# Start the main loop
root.mainloop()

Output:

a colorful ttk Notebook GUI with three tabs positioned at the bottom. The tabs are styled with a yellow background, orange text, and bold Helvetica font. The first tab labeled ' Apple' displays a green apple emoji. The second tab labeled ' Banana' displays a yellow banana emoji. The third tab labeled ' Cherry' displays a red cherry emoji.

Styling Options

Here’s a table summarizing the styling options for TNotebook and TNotebook.Tab. Some styling options are only applicable to specific themes, so keep that in mind.

TNotebook Styling Options :

OptionsDescription
backgroundBackground color of the notebook.
bordercolorColor of the notebook’s border.
darkcolorColor for adding depth and visibility.
foregroundText and icon colors in the notebook.
lightcolorColor for highlights or subtle effects.
paddingSpace around the elements within the notebook.
tabmarginsSpacing between tabs and frames.
tabpositionPosition of the tabs. The values should be n, s, e, and w.

TNotebook.Tab Styling Options :

OptionsDescription
backgroundBackground color of individual tabs.
bordercolorColor of the tab’s border.
compoundCombines text and images on tabs.
foregroundColor of the text on individual tabs.
fontFont style for the tab labels.
paddingSpace within tabs to enhance aesthetics.
expandDefines how much a tab expands when selected. The value should be an integer like 2, 6,10.

Style with Dynamic States

You can also style the ttk Notebook and its tabs for different states:

ActiveThis state represents when the notebook or tab is currently active.
DisabledIn this state, the notebook or tab is not available for interaction.
SelectedThe selected state shows which tab is currently in use.

Example:

import tkinter as tk
from tkinter import ttk

# Create the main application window
root = tk.Tk()
root.title("Adventure Quest Tabs")
root.geometry("800x600")

# Set a theme and create a new Style for the ttk notebook
style = ttk.Style()
style.theme_use("clam")

# Configure TNotebook with a custom "MagicNotebook" style
style.configure("MagicNotebook.TNotebook",
                background="purple", 
                borderwidth=3,
                tabposition='n',  # Positioning tabs at the top
                tabmargins=10, 
                padding=15)

# Configure dynamic states for TNotebook.Tab with a "MagicNotebook" style
style.map("MagicNotebook.TNotebook.Tab",
          background=[("active", "#FFDD44"),  # Golden for active tab
                      ("selected", "#BB00BB")],  # Purple for selected
          foreground=[("selected", "white")])

# Configure static styling for TNotebook.Tab
style.configure("MagicNotebook.TNotebook.Tab",
                background="blue", 
                foreground="lightyellow",
                padding=(20, 10), 
                font=("Courier", 12, "bold"))

# Create the Notebook widget
notebook = ttk.Notebook(root, style="MagicNotebook.TNotebook")
notebook.pack(pady=10, padx=20, expand=True, fill='both')

# Create frames for each adventure-themed tab
frame1 = ttk.Frame(notebook, width=400, height=280)
frame2 = ttk.Frame(notebook, width=400, height=280)
frame3 = ttk.Frame(notebook, width=400, height=280)

# Add frames as tabs with colorful icons and text
notebook.add(frame1, text='🧙 Wizardry')
notebook.add(frame2, text='🛡️ Warrior')
notebook.add(frame3, text='🌌 Sorcery')

# Adding content to each tab to match the theme
label1 = tk.Label(frame1, text="Welcome to the Wizardry tab!\nCast spells and brew potions.", font=("Courier", 14), fg="purple")
label1.pack(pady=20)

label2 = tk.Label(frame2, text="Welcome to the Warrior tab!\nPrepare for battle and defend the realm.", font=("Courier", 14), fg="darkred")
label2.pack(pady=20)

label3 = tk.Label(frame3, text="Welcome to the Sorcery tab!\nExplore the cosmos and bend time.", font=("Courier", 14), fg="darkblue")
label3.pack(pady=20)

# Start the main loop
root.mainloop()

Output:

a customized ttk Notebook GUI application with an 'Adventure Quest Tabs' theme. The notebook has a purple background with three tabs at the top. Each tab displays a colorful themed icon (wizard hat, shield, and stars) and bold text ('Wizardry', 'Warrior', 'Sorcery'). Content within each tab is themed accordingly (wizardry, warrior, and sorcery)

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *