The problem I'm facing is simple:
I have a tkinter window with root.overrideredirect(True)
and hence, I had to make my own move_window(event)
with the corresponding binding. It does work, but the moment I drag it with my mouse, the the window relocates such that the top-left corner of the window is at my mouse location.
What I want:
Smooth dragging like we do with our everyday apps.
Code for window and move function with bindings:
from tkinter import *
import pyautogui as pg
bg_color= '#ededed'
root = Tk()
root.overrideredirect(True)
root.title("Google Drive")
root.geometry("1000x600")
root.update()
# Creating a canvas for placing the squircle shape.
canvas = Canvas(root, height=root.winfo_height(), width=root.winfo_width(), highlightthickness=0)
canvas.pack(fill='both')
canvas.update()
# make a frame for the title bar
title_bar = Frame(canvas, bg=bg_color, relief='raised', bd=0)
title_bar.pack(expand=1,fill='x')
title_bar.update()
# put a close button on the title bar
close_button = Button(title_bar, text='X', command= root.destroy,padx = 2,pady = 2,bd = 0,font="bold",highlightthickness=0)
close_button.pack(side='right')
close_button.update()
# a canvas for the main area of the window
window = Canvas(canvas, bg=bg_color,highlightthickness=0)
window.pack(expand=1,fill='both')
window.update()
# Placing the window in the center of the screen
def place_center():
global x, y
reso = pg.size()
rx = reso[0]
ry = reso[1]
x = int((rx/2) - (root.winfo_width()/2))
y = int((ry/2) - (root.winfo_height()/2))
root.geometry(f" {x} {y}")
# Bind Functions
def move_window(event):
root.geometry(' {0} {1}'.format(event.x_root, event.y_root))
def change_on_hovering(event):
global close_button
close_button['bg']= 'white'
def return_to_normalstate(event):
global close_button
close_button['bg']= 'black'
xwin=None
ywin=None
# Bindings
title_bar.bind('<B1-Motion>', move_window)
close_button.bind('<Enter>',change_on_hovering)
close_button.bind('<Leave>',return_to_normalstate)
# Function Calls
place_center()
root.mainloop()
Here's another move function I tried but the window kinda glitches
def move_window(event):
relx = pg.position().x - root.winfo_x()
rely = pg.position().y - root.winfo_y()
root.geometry(' {0} {1}'.format(relx, rely))
Any ideas? I suspect it to be a simple mathematical calculation
CodePudding user response:
You need to compute the distance that the mouse has moved since the last time the event was handled, and then add that change to the current location of the window.
You can do this by first setting a binding on the button click to save the location of the cursor. Then, as the window is moved you need to get the new location, calculate the difference from the old location, and then apply that to the current location of the window.
It looks something like this:
def start_move(event):
global lastx, lasty
lastx = event.x_root
lasty = event.y_root
def move_window(event):
global lastx, lasty
deltax = event.x_root - lastx
deltay = event.y_root - lasty
x = root.winfo_x() deltax
y = root.winfo_y() deltay
root.geometry(" %s %s" % (x, y))
lastx = event.x_root
lasty = event.y_root
...
title_bar.bind("<ButtonPress-1>", start_move)
title_bar.bind('<B1-Motion>', move_window)
...
CodePudding user response:
You could try something like this:
def move_window(event):
x = event.x_root - root.winfo_x()
y = event.y_root - root.winfo_y()
root.geometry(" %s %s" % (x, y))