Reputation: 93
I tried to change the mouse tip with a Canvas created red cirlce OR a yellow Label with "X" on it.
I used a "where" fucntion, which traps the mouse movement, and provides me with the current position of the mouse tip, so place either one of the above tips, ie red circle or yellow label at the mounse tip position.
I realise that if they are placed right at the mouse tip, is not so desirable as it can mask the underlying widgets, but let's put that aside.
Using the following code, you'll realize that the selected tip is offset from the actual mouse tip, while I actually place then right at the tip. So why is the offset ? What is wrong?
I also realise that placement means placing the nw corner of the widget.
This sample program can let you select the tip to play with, by clicking on the other tip, to swap to it.
So, you can see, by selecting either tip shape, the behaviour is the same.
import tkinter as tk
def changetip(a): # change cursor tip, arg a is not used
global tipType
if tipType=="red" : tipType="yellow"
else: tipType="red"
def where(posn): #cursor tiop movement and colour change
cx=posn.x_root-w.winfo_x()
cy=posn.y_root-w.winfo_y()
if tipType=="red":
tipC.place(x=cx, y=cy)
tipL.place(x=300,y=300)
else:
tipC.place(x=400, y=400)
tipL.place(x=cx,y=cy)
w=tk.Tk()
w.geometry("500x500+100+100")
w.bind("<Motion>",where) #track mouse movement
tipType="red" # red is the canvas circle, yellow is label
# Make a cursor tip using a circle on canvas
tip_rad=10
tipC=tk.Canvas(w,width=tip_rad*2,height=tip_rad*2,highlightthickness=0,bg="green")
tip=tk.Canvas.create_oval(tipC,tip_rad/2,tip_rad/2,tip_rad/2*3,tip_rad/2*3, width=0, fill="red")
tipC.bind("<1>",changetip)
# Make a cursor tip using a label
tip_size=1
tipL=tk.Label(w,width=tip_size, height=tip_size,text="x",bg="yellow")
tipL.bind("<1>",changetip)
w.mainloop()
Upvotes: 2
Views: 3620
Reputation: 10906
You should ignore the event object (posn
) and work only with pixel positions that are relative to the main widget w
. Change the first two lines of where
as follows:
def where(posn):
cx=w.winfo_pointerx() - w.winfo_rootx()
cy=w.winfo_pointery() - w.winfo_rooty()
Upvotes: 2