1
votes

In using the code reproduced below, I noticed that in both Press-Release and Motion actions, tkinter reports negative event.x values when we move the mouse from right to left.

My question: for the purposes of identifying correctly the widget that the mouse finally rested, whatever the direction taken, what is the correct way of identifying the (event.x, event.y) points in the containing frame?

#!/usr/bin/env python3
from tkinter import *

root = Tk()

def press(event):
    print(f"{event.widget} clicked at: {event.x, event.y}")
    print(f"{event.widget.grid_info()}")

def release(event):
    print("RELEASE")
    end_x, end_y = event.x, event.y
    print(f"{end_x, end_y}")
    locate(end_x, end_y)

def motion(event):
    print(f"{event.widget}: mouse position motion at {event.x, event.y}")

def locate(end_x, end_y):
    end_x = int(end_x)
    end_y = int(end_y)
    print(f"Released at {fr.grid_location(end_x, end_y)}")
    end_col, end_row = fr.grid_location(end_x, end_y)
    print(end_col, end_row)
    print(f"Actual frame info: {fr.grid_info()}")

fr = Frame(root, width=200, height=300,bg="dark blue")
fr.grid(sticky=NSEW, padx=2, pady=2)
lbl1 = Label(master=fr, text="LABEL 1", padx=2, pady=2, width=10, relief=SUNKEN)
lbl1.grid(column=0, row=0, sticky=NSEW)
lbl2 = Label(master=fr, text="LABEL 2", padx=2, pady=2, width=10, relief=SUNKEN)
lbl2.grid(column=1, row=0, sticky=NSEW)
lbl3 = Label(master=fr, text="LABEL 3", padx=2, pady=2, width=10, relief=SUNKEN)
lbl3.grid(column=2, row=0, sticky=NSEW)
lbl4 = Label(master=fr, text="LABEL 4", padx=2, pady=2, width=10, relief=SUNKEN)
lbl4.grid(column=0, row=1, sticky=NSEW)
lbl5 = Label(master=fr, text="LABEL 5", padx=2, pady=2, width=10, relief=SUNKEN)
lbl5.grid(column=1, row=1, sticky=NSEW)
lbl6 = Label(master=fr, text="LABEL 6", padx=2, pady=2, width=10, relief=SUNKEN)
lbl6.grid(column=2, row=1, sticky=NSEW)

lbl1.bind_all("<Button-1>", press)
lbl1.bind_all("<ButtonRelease-1>", release)
lbl1.bind_all("<B3-Motion>", motion)
lbl1.bind_all("<ButtonRelease-3>", release)

root.mainloop()

Thanks.

1

1 Answers

0
votes

for the purposes of identifying correctly the widget that the mouse finally rested, whatever the direction taken, what is the correct way of identifying the (event.x, event.y) points in the containing frame?

The x/y coordinates of the release event are relative to the widget that got the press event, which explains why the values can be negative.

The coordinates to use for finding the widget under the cursor are event.x_root and event.y_root, which you can pass to winfo_containing to get the actual widget.

For example:

def release(event):
    window = root.winfo_containing(event.x_root, event.y_root)
    print(f"window under the cursor: {window}")