Tjaart
Tjaart

Reputation: 496

Tkinter: Detecting a window drag event

I have an animation running in my window, which I would like to pause whenever the user drags the window, to ensure a smooth interaction.

I have tried the following:

root.bind("<ButtonPress-1>", lambda e: start_stop_animation(False))
root.bind("<B1-Motion>", lambda e: start_stop_animation(False))
root.bind("<ButtonRelease-1>", lambda e: start_stop_animation(self._is_running))

It seems that these calls do not bind to the title bar at all.

I would like to do this without removing the title bar using root.overrideredirect(True), unless there is a simple way of replacing it with a similar title bar capable of capturing these events.

Upvotes: 0

Views: 3164

Answers (1)

j_4321
j_4321

Reputation: 16169

Window dragging is captured by the <Configure> event, which is also triggered by window resizing.

To execute different actions at the beginning of the dragging, during the dragging and at end, you can use the after method:

Each time a <Configure> event happens, you schedule a call to your stop_drag function with a given delay, but you cancel this call each time another <Configure> event happens before the end of the delay.

import tkinter as tk

root = tk.Tk()

drag_id = ''


def dragging(event):
    global drag_id
    if event.widget is root:  # do nothing if the event is triggered by one of root's children
        if drag_id == '':
            # action on drag start
            print('start drag')
        else:
            # cancel scheduled call to stop_drag
            root.after_cancel(drag_id)
            print('dragging')
        # schedule stop_drag
        drag_id = root.after(100, stop_drag)


def stop_drag():
    global drag_id
    print('stop drag')
    # reset drag_id to be able to detect the start of next dragging
    drag_id = '' 


root.bind('<Configure>', dragging)
root.mainloop()

Upvotes: 6

Related Questions