ttk PanedWindow

In Tkinter, the ttk Panedwindow serves as an enhanced version of the standard tkinter Panedwindow widget. While both widgets essentially provide a way to create resizable panes within a window, the ttk version offers a more modern look and feel.

If you’re not familiar with resizable panes in a window, let me explain it to you. Resizable panes are like sections in a window that you can adjust in size. This feature is handy because it allows users to customize their workspace according to their needs.

But if you’re still not getting it, that’s okay! We’ll look at a real-life example of paned windows later in this tutorial, which should make things clearer.

This tutorial will show you how to make and change the appearance of paned windows to fit your style. We’ll also cover how to make things happen when you click or interact with the ttk Panedwindow. By the end, you’ll know how to use this tool to make your Python programs look and work better.

Create Your First ttk Panedwindow

Now, let’s get started on making your first ttk Panedwindow!

Example:

# First, we need to import the necessary modules
from tkinter import *
from tkinter import ttk

# Then, we create a Tkinter root window
root = Tk()
root.grid_anchor(anchor='center')  # This centers the window on the screen

# Next, we'll set up some styles for our ttk Panedwindow
style = ttk.Style()

style.theme_use('clam')  # Use the 'clam' theme
style.configure("design1.TFrame", background='black')  # Style for the first frame
style.configure("design2.TFrame", background='grey')   # Style for the second frame

# Now, let's create a horizontal ttk Panedwindow
panewin1 = ttk.Panedwindow(root, height=400, width=600, orient='horizontal')

# Inside the Panedwindow, we'll add two frames with different styles
frame1 = ttk.Frame(panewin1, width=300, style="design1.TFrame")  # First frame with design1 style
frame2 = ttk.Frame(panewin1, width=300, style="design2.TFrame")  # Second frame with design2 style

# Add the frames to the Panedwindow
panewin1.add(frame1)
panewin1.add(frame2)

# Finally, we'll position the horizontal Panedwindow in the root window
panewin1.grid(row=0, column=0)

# Now, let's create a vertical ttk Panedwindow
panewin2 = ttk.Panedwindow(root, height=400, width=600, orient='vertical')

# Inside the vertical Panedwindow, add two frames with different styles
frame3 = ttk.Frame(panewin2, height=200, style="design2.TFrame")  # First frame with design2 style
frame4 = ttk.Frame(panewin2, height=200, style="design1.TFrame")  # Second frame with design1 style

# Add the frames to the vertical Panedwindow
panewin2.add(frame3)
panewin2.add(frame4)

# Position the vertical Panedwindow in the root window
panewin2.grid(row=1, column=0)

# Finally, start the Tkinter event loop
root.mainloop()

Output:

simple ttk panedwindow

ttk Panedwindow Customization

The most commonly used options for customizing ttk Panedwindow are:

heightSets the initial height of the paned window.
widthDetermines the initial width of the paned window.
orientThis option lets you choose how your panels will be arranged—either vertically or horizontally.

Other Standard Options:

  • cursor
  • style
  • takefocus

If you’re curious to learn more about these options, you should see Tkinter Standard Options and ttk and ttk style.

Styling Your ttk Panedwindow

You can customize the appearance of your ttk Panedwindow using styles. To target the ttk Panedwindow, you can use the class name 'TPanedwindow' within the ttk style.

style = ttk.Style()
style.configure("TPanedwindow", background='yellow')

However, there’s only one style configuration option available for 'TPanedwindow', which is background.

If you want a different background color for certain ttk Panedwindows, you can create custom class names. You can do this by adding a unique name before the base class name. For example:

style = ttk.Style()
style.configure("design.TPanedwindow", background='yellow')

This way, you can apply customized styles to individual ttk Panedwindows.

Additionally, if you wish to style the sash (the divider between panes) of the paned window, you can use the class name "Sash" and adjust its appearance using these style configuration options:

backgroundChanges the background color of the sash.
sashpadAdjusts the padding around the sash.
sashthicknessSets the thickness of the sash.
gripcountDetermines the number of grips (handles) on the sash.
handlepadSpecifies the padding around the grip (handle) on the sash.

Remember, all options are not applied to all themes so use themes like “classic” or “clam”.

Example:

from tkinter import *
from tkinter import ttk

root=Tk()
root.grid_anchor(anchor='center')

style=ttk.Style()

style.theme_use('clam')

style.configure("design.TPanedwindow", background='yellow')
style.configure("Sash", gripcount=10, sashthickness=80)
        
style.configure("design1.TFrame", background='red')
style.configure("design2.TFrame", background='blue')

panewin=ttk.Panedwindow(root, height=500, width=600, orient='horizontal', style='design.TPanedwindow')

frame1=ttk.Frame(panewin, width=300, style="design1.TFrame")
frame2=ttk.Frame(panewin, width=300, style="design2.TFrame")

panewin.add(frame1)
panewin.add(frame2)

panewin.grid(row=0, column=0)

root.mainloop()

Output:

ttk panedwindow with style

ttk Panedwindow With Different Themes

Themes are like different styles or appearances that you can apply to your tkinter application to change its overall look and feel. You can easily switch between different themes to see how they affect the appearance of your paned window.

Example:

from tkinter import *
from tkinter import ttk

root=Tk()
root.grid_anchor(anchor='center')

style=ttk.Style()


def changetheme():
    themeval=themevar.get()
    style.theme_use(themeval)
    
    style.configure("design.TPanedwindow", background='yellow')
    style.configure("Sash", background='red', handlepad=300, gripcount=100, sashthickness=20, sashpad=50)
    
    style.configure("design1.TFrame", background='green')
    style.configure("design2.TFrame", background='orange')
     
themevar=StringVar()
themevar.set("vista")

btn1=ttk.Radiobutton(root,text='winnative theme',value="winnative",command=changetheme,variable=themevar,style='Toolbutton')
btn2=ttk.Radiobutton(root,text='clam theme',value="clam",command=changetheme,variable=themevar,style='Toolbutton')
btn3=ttk.Radiobutton(root,text='alt theme',value="alt",command=changetheme,variable=themevar,style='Toolbutton')
btn4=ttk.Radiobutton(root,text='classic theme',value="classic",command=changetheme,variable=themevar,style='Toolbutton')
btn5=ttk.Radiobutton(root,text='vista theme',value="vista",command=changetheme,variable=themevar,style='Toolbutton')
btn6=ttk.Radiobutton(root,text='xpnative theme',value="xpnative",command=changetheme,variable=themevar,style='Toolbutton')

btn1.grid(row=1,column=0)
btn2.grid(row=1,column=1)
btn3.grid(row=1,column=2)
btn4.grid(row=2,column=0)
btn5.grid(row=2,column=1)
btn6.grid(row=2,column=2)

changetheme()

panewin=ttk.Panedwindow(root, height=500, width=600, orient='horizontal', style='design.TPanedwindow')

frame1=ttk.Frame(panewin, width=300, style="design1.TFrame")
frame2=ttk.Frame(panewin, width=300, style="design2.TFrame")

panewin.add(frame1)
panewin.add(frame2)

panewin.grid(row=0, column=0, columnspan=3)

root.mainloop()

Output:

ttk panedwindow with different themes


Some Essential Methods

To make your ttk PanedWindow work smoothly, it’s good to know these key methods:

The add() method adds a new section, called a pane, to your PanedWindow. Just tell it which widget you want to add, and you can also decide how much space it should take up. For example: paned_window.add(widget, weight).

Similar to add(), insert() lets you add a new pane at a specific spot in your PanedWindow. You just need to specify the position where you want to add the pane and the widget you want to add. For example: paned_window.insert(0, widget).

The sashpos() method helps you move the divider (called a sash) between panes. You can change its position to adjust the layout of your PanedWindow. For example: paned_window.sashpos(0, new_position).

Example:

from tkinter import *
from tkinter import ttk

root=Tk()
root.grid_anchor(anchor='center')
style=ttk.Style()

style.configure("design1.TPanedwindow",background='lightgreen')

style.configure("design1.TFrame",background='orange')
style.configure("design2.TFrame",background='blue')

panewin1=ttk.Panedwindow(root,height=300,width=600,orient='horizontal',style='design1.TPanedwindow')

frame1=ttk.Frame(panewin1,style="design1.TFrame")
frame2=ttk.Frame(panewin1,style="design2.TFrame")

panewin1.add(frame1,weight=2)
panewin1.add(frame2,weight=1)

panewin1.grid(row=0,column=0)

def insertpane():
    newpane=ttk.Label(panewin1, text="new pane", background="green", foreground='white')
    # insert() method is used to insert a pane at a specific position
    panewin1.insert(frame2,newpane) 
        
insertpanebtn=ttk.Button(root, text="Insert Pane Inside The Panedwindow", command=insertpane)
insertpanebtn.grid()   

# sashpos() is used to position a specific sash at a particular position
positionsashbtn=ttk.Button(root, text="Position A Sash By Using sashpos()", command=lambda:panewin1.sashpos(0,200))
positionsashbtn.grid()   

root.mainloop()

Output:

showing the use of specific ttk panedwindow commands

In addition to the essential methods we’ve covered, ttk PanedWindow also supports some other handy methods inherited from tkinter PanedWindow:

  • forget()
  • pane()
  • panes()
  • cget()
  • configure()

If you’re curious to learn more about these methods, you can find detailed explanations in the Tkinter Panedwindow.

Binding Events with ttk PanedWindow

Let’s explore how to add interactivity to a ttk PanedWindow in Tkinter by binding events. In this example, we’ll create a fun feature where the panes change colors while resizing. And when you stop resizing, the colors will go back to their original ones!

Example:

import tkinter as tk
from tkinter import ttk

def handle_resize(event):
    style.configure("custom1.TFrame", background="red")
    style.configure("custom2.TFrame", background="green")

def handle_release(event):
    style.configure("custom1.TFrame", background="pink")
    style.configure("custom2.TFrame", background="lightgreen")

root = tk.Tk()
root.title("Binding Events with ttk PanedWindow")

style = ttk.Style()
style.configure("custom1.TFrame", background="pink")
style.configure("custom2.TFrame", background="lightgreen")

# Create a ttk PanedWindow with horizontal orientation
paned_window = ttk.PanedWindow(root, orient=tk.HORIZONTAL)
paned_window.pack(expand=True, fill=tk.BOTH)

# Create two frames to be added as panes in the PanedWindow
pane1 = ttk.Frame(paned_window, width=200, height=200, relief=tk.SUNKEN, style="custom1.TFrame")
pane2 = ttk.Frame(paned_window, width=200, height=200, relief=tk.SUNKEN, style="custom2.TFrame")

# Add the frames as panes in the PanedWindow
paned_window.add(pane1)
paned_window.add(pane2)

# Bind the <B1-Motion> event to the handle_resize function
paned_window.bind("<B1-Motion>", handle_resize)

# Bind the <ButtonRelease-1> event to the handle_release function
paned_window.bind("<ButtonRelease-1>", handle_release)

root.mainloop()

Output:

Tkinter PanedWindow with dynamic color changes: the left pane turns red while resizing (mouse move) and pink when released; the right pane turns green while resizing and light green when released. Demonstrates event binding with Tkinter and ttk.

Real World Example : Modern Task Manager with Resizable Panes

Imagine a task manager that helps you keep track of your daily tasks. With Tkinter and ttk PanedWindow, we can make it happen! Our task manager will let you change the size of different sections so you can set it up just how you like it.

Example:

import tkinter as tk
from tkinter import ttk

def select_task(event):
    selected_task = task_listbox.curselection()
    if selected_task:
        task_details_text.delete("1.0", "end")
        task_details_text.insert("end", task_data[selected_task[0]])

# Sample task data
task_data = [
    "Task 1 Details: This is a sample task.",
    "Task 2 Details: Another sample task.",
    "Task 3 Details: Yet another sample task."
]

# Create main window
root = tk.Tk()
root.title("Streamlined Task Manager")

# Configure style
style = ttk.Style()
style.theme_use("clam")
style.configure("TFrame", background="#f0f0f0")
style.configure("TLabel", background="#f0f0f0", foreground="#333", font=("Helvetica", 12))
style.configure("TButton", background="#4CAF50", foreground="white", font=("Helvetica", 12))
style.map("TButton", background=[("active", "#45a049")])

# Create ttk PanedWindow
paned_window = ttk.PanedWindow(root, orient=tk.HORIZONTAL)
paned_window.pack(expand=True, fill=tk.BOTH)

# Task list pane
task_list_pane = ttk.Frame(paned_window)
paned_window.add(task_list_pane)

# Task details pane
task_details_pane = ttk.Frame(paned_window)
paned_window.add(task_details_pane)

# Task list
task_listbox = tk.Listbox(task_list_pane, width=30, height=10, bg="#f0f0f0", fg="#333", font=("Helvetica", 12))
task_listbox.pack(expand=True, fill=tk.BOTH)
for task in range(len(task_data)):
    task_listbox.insert(tk.END, f"Task {task+1}")

# Task details
task_details_text = tk.Text(task_details_pane, width=50, height=10, bg="#f0f0f0", fg="#333", font=("Helvetica", 12))
task_details_text.pack(expand=True, fill=tk.BOTH)

# Bind events
task_listbox.bind("<<ListboxSelect>>", select_task)

root.mainloop()

Explanation:

  • We’ve created a stylish and modern task manager GUI using Tkinter and ttk PanedWindow.
  • The task manager features two resizable panes: one for the task list and the other for task details.
  • You can select a task from the list, and its details will be displayed in the adjacent pane.
  • The GUI is styled using the “clam” theme from ttk, with custom colors, fonts, and button styles.

Output:

Tkinter task list, task details, PanedWindow, interactive Python GUI, task management app, Tkinter styling, clam theme.

Similar Posts

Leave a Reply

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