Any suggestions on how one might create event bindings that would allow a user to mouse drag a window without borders, eg. a window created with overridedirect(1)
?
Use case: We would like to create a floating toolbar/palette window (without borders) that our users can drag around on their desktop.
Here’s where I’m at in my thinking (pseudo code):
window.bind( '<Button-1>', onMouseDown )
to capture the initial position of the mouse.window.bind( '<Motion-1>', onMouseMove )
to track position of mouse once it starts to move.Calculate how much mouse has moved and calculate
newX
,newY
positions.Use
window.geometry( '+%d+%d' % ( newX, newY ) )
to move window.
Does Tkinter expose enough functionality to allow me to implement the task at hand? Or are there easier/higher-level ways to achieve what I want to do?
Advertisement
Answer
Yes, Tkinter exposes enough functionality to do this, and no, there are no easier/higher-level ways to achive what you want to do. You pretty much have the right idea.
Here’s one example, though it’s not the only way:
import tkinter as tk class App(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.floater = FloatingWindow(self) class FloatingWindow(tk.Toplevel): def __init__(self, *args, **kwargs): tk.Toplevel.__init__(self, *args, **kwargs) self.overrideredirect(True) self.label = tk.Label(self, text="Click on the grip to move") self.grip = tk.Label(self, bitmap="gray25") self.grip.pack(side="left", fill="y") self.label.pack(side="right", fill="both", expand=True) self.grip.bind("<ButtonPress-1>", self.start_move) self.grip.bind("<ButtonRelease-1>", self.stop_move) self.grip.bind("<B1-Motion>", self.do_move) def start_move(self, event): self.x = event.x self.y = event.y def stop_move(self, event): self.x = None self.y = None def do_move(self, event): deltax = event.x - self.x deltay = event.y - self.y x = self.winfo_x() + deltax y = self.winfo_y() + deltay self.geometry(f"+{x}+{y}") app=App() app.mainloop()