Reputation: 2241
I have a tkinter PanedWindow containing some widgets and I want the user to be able to drag each separator to a certain position and when they let go of the mouse button, the separator should "snap" to the nearest position in a list of positions / proportions I give the program. For example, let's say I have a PanedWindow containing two buttons, and I want the user to be able to resize the buttons such that they can be in the proportions 1/4:3/4, 1/2:1/2 or 3/4:1/4 not just any width the user chooses. Is there a way I can do this? Code for PanedWindow with two buttons:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("400x400")
pw = tk.PanedWindow(root)
buttons = [ttk.Button(text=message) for message in ["goose", "duck"]]
for button in buttons:
pw.add(button)
pw.pack(expand=True, fill="both")
root.mainloop()
Is there a way to specify the proportions the separators can snap to?
Allowed positions:
The buttons should snap to the nearest of these positions when resized.
Upvotes: 3
Views: 479
Reputation: 3089
You can do this by binding <ButtonRelease-1>
to a function that calculates the closest point. You can then use this information and update the sash position using PanedWindow.sash_place(index, x, y)
.
Here is a minimal example:
import tkinter as tk
from tkinter import ttk
def snap(event):
width = pw.winfo_width()
closest = min([width//2, width//4, width*3//4], key=lambda w: abs(w - event.x))
pw.sash_place(0, closest, 1)
root = tk.Tk()
root.title("snappy")
pw = tk.PanedWindow(root)
buttons = [ttk.Button(text=message) for message in ["goose", "duck"]]
for button in buttons:
pw.add(button)
pw.pack(expand=True, fill="both")
pw.bind("<ButtonRelease-1>", snap)
root.mainloop()
Upvotes: 5