简体   繁体   中英

Why is the button moving incorrectly

Run this code before answering -

from tkinter import *

root = Tk()
root.geometry('500x500')

def drag(e):
    posx,posy = e.x_root,e.y
    B1.place(x=posx,y=posy)

def size(event):
    W,H,X,Y = event.width,event.height,event.x,event.y
    root.title(f'W: {W}, H: {H}, X: {X}, Y: {Y}')

root.bind('<Configure>',size)

B1 = Button(root,text='Hi')
B1.place(x=0,y=0)

B1.bind("<B1-Motion>",drag)

Result:

在此处输入图片说明

When I try to move the button, it goes smoothly. But if I move the whole Tkinter window and then move the button, it goes somewhere else.

So, how do I fix it so that it is smooth?

EDIT: When I use ex ..., 2 buttons are shown

Problem is because functions use different coordinates - event.x_root gives position on screen, not in window, and place() needs position in window, not on screen. There is also event.x which gives position inside button so it may not be useful.

You can use root.winfo_rootx() (which gives window position) to correct it.
You could also get mouse position on Button when you click it to correct its position when you move Button .

import tkinter as tk  # PEP8: `import *` is not preferred

# --- functions ---

def start(e):
    global offsetx
    global offsety
    
    offsetx = e.x
    offsety = e.y
    
    print(offsetx, offsety)
    
def drag(e):
    posx = e.x_root - root.winfo_rootx() - offsetx
    posy = e.y_root - root.winfo_rooty() - offsety
    button1.place(x=posx, y=posy)

# --- main ---

root = tk.Tk()
root.geometry('500x500')

button1 = tk.Button(root, text='Hi')   # PEP8: `lower_case_names` for variables
button1.place(x=0, y=0)

button1.bind("<ButtonPress-1>", start)
button1.bind("<Button1-Motion>", drag)

root.mainloop()

PEP 8 - Style Guide for Python Code


EDIT:

Other method using e.widget to get widget position and relative ex,ey

def drag(e):
    widget = e.widget
    
    posx = widget.winfo_x() + e.x - offsetx
    posy = widget.winfo_y() + e.y - offsety

    button1.place(x=posx, y=posy)

This answer should help you fix it. event.x_root is taking the screen coordinates and not the widget coordinates. Use event.x instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM