Search code examples
pythontkinterttk

How to change the height (or width) of tkinter widget with mouse drag, after initialization?


The closest approach I found was by packing the widgets separated with ttk.Separator changing the cursor and triggering a function that resizes the top and bottom widgets when the mouse starts clicked motion on the separator. The problem is, it is not working because of the glitch I am getting, and I could not find out the cause. Please check the code below:

import tkinter as tk

from tkinter import ttk

from ttkwidgets.autocomplete import AutocompleteEntryListbox

def resize(event):
    searchbox.config(height=searchbox.winfo_height()+event.y)
    template.config(height=template.winfo_height()-event.y)

window = tk.Tk()

frame_navigator = tk.Frame(window)

frame_navigator.configure(background="white",width=300,height=300)
frame_navigator.pack_propagate(0)

searchbox = AutocompleteEntryListbox(frame_navigator,completevalues=[],allow_other_values=False)
searchbox.pack(side=tk.TOP,expand=1,fill=tk.BOTH)

separator = ttk.Separator(frame_navigator,orient='horizontal',cursor="size_ns")
separator.bind("<B1-Motion>",resize)
separator.pack(side=tk.TOP,fill=tk.X)

template = tk.Listbox(frame_navigator,exportselection=False)
template.pack(side=tk.TOP,expand=1,fill=tk.BOTH)

frame_navigator.pack(side=tk.TOP,expand=1,fill=tk.BOTH)

Your help will be appreciated!


Solution

  • I don't have ttkwidgets installed but I replaced AutocompleteEntryListbox with tk.Listbox for testing and found a solution that worked using tk.PanedWindow, a widget specifically designed for doing this. There is no reason it shouldn't work with a different widget. Set the orient of the PanedWindow to tkinter.constants.VERTICAL to change the height, and use frame_navigator.add() instead of widget.pack() for it to work. Completed code:

    import tkinter as tk
    from tkinter.constants import *
    
    window = tk.Tk()
    
    frame_navigator = tk.PanedWindow(window, orient=VERTICAL)
    
    frame_navigator.configure(background="white", width=300, height=300)
    frame_navigator.pack_propagate(0)
    
    searchbox = tk.Listbox(frame_navigator)
    frame_navigator.add(searchbox)
    
    template = tk.Listbox(frame_navigator, exportselection=False)
    frame_navigator.add(template)
    
    frame_navigator.pack(side=tk.TOP, expand=1, fill=tk.BOTH)
    
    window.mainloop()