最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Cursor not always updating in Tkinter - Stack Overflow

programmeradmin4浏览0评论

I'm trying to change the cursor in my Tkinter app when the mouse moves. As a simplified example:

import tkinter as tk

root = tk.Tk()
root.geometry("500x200")

frame2 = tk.Frame(root)
frame = tk.Canvas(frame2)

def on_mouse_motion(event):
    if event.x > 200:
        frame2.config(cursor="xterm")
    else:
        frame2.config(cursor="crosshair")

frame.bind("<Motion>", on_mouse_motion)

frame.pack(expand=True, fill="both")
frame2.pack(expand=True, fill="both")
root.mainloop()

However, the cursor updates the first one or two times and then stops changing.

I've noticed that it works if I change the cursor on the Canvas and not the container, but because of limitations with the widget I'm working with (which is a non-standard widget but also faces the same problem), that's not possible. I've tried using update and update_idletasks, but with no avail. The only thing that seems to work is if I put print() in the callback, which is kind of wierd, and not a fantastic solution.

I was wondering if anyone has encountered this issue in the past and knows how to work around/fix it?

I'm trying to change the cursor in my Tkinter app when the mouse moves. As a simplified example:

import tkinter as tk

root = tk.Tk()
root.geometry("500x200")

frame2 = tk.Frame(root)
frame = tk.Canvas(frame2)

def on_mouse_motion(event):
    if event.x > 200:
        frame2.config(cursor="xterm")
    else:
        frame2.config(cursor="crosshair")

frame.bind("<Motion>", on_mouse_motion)

frame.pack(expand=True, fill="both")
frame2.pack(expand=True, fill="both")
root.mainloop()

However, the cursor updates the first one or two times and then stops changing.

I've noticed that it works if I change the cursor on the Canvas and not the container, but because of limitations with the widget I'm working with (which is a non-standard widget but also faces the same problem), that's not possible. I've tried using update and update_idletasks, but with no avail. The only thing that seems to work is if I put print() in the callback, which is kind of wierd, and not a fantastic solution.

I was wondering if anyone has encountered this issue in the past and knows how to work around/fix it?

Share Improve this question edited yesterday Andereoo asked yesterday AndereooAndereoo 9581 gold badge9 silver badges28 bronze badges 5
  • What is the output of event.x being 200. That's what pops to me as a potential issue...your code is like 15 lines. It sounds like your cursor is having issues after a few movements, that's the only place that changes – ViaTech Commented yesterday
  • My actual code is a lot more complicated...using event.x > 200 is just a placebo to show the problem. No issues there. I can print event.x to check but then it works! – Andereoo Commented yesterday
  • what occurs when you store the value of x in a variable and use that instead of event.x? Perhaps you are having an issue with the event object not doing what you expect. A global tracker of where the mouse is doesn't sound like a bad option anyways – ViaTech Commented yesterday
  • Still doesn't work. Even if i use something other than event.x to decide what the cursor to be (i.e. random # generator, etc) the cursor still refuses to update. Tkinter bug? – Andereoo Commented yesterday
  • Your code works fine in my Windows 11 with Python 3.13.2. – acw1668 Commented 21 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

I couldn't find any issue per se, am not really sure what the issue is , added a couple some 'feedback' to your code , hopefully that will help you ... if not ... you need to better explain what you think the issue is ...

import tkinter as tk

root = tk.Tk()
root.title("Event-Driven Messages in Frame")
root.geometry("500x200")

frame2 = tk.Frame(root)
frame = tk.Canvas(frame2)


message_label = tk.Label(frame, text="", bg="lightgray", font=("Arial", 16))
message_label.pack(pady=20)


def on_mouse_motion(event):
    if event.x > 200:
        frame2.config(cursor="xterm")
        message_label.config(text=f"XTERM: x:{event.x}, y:{event.y})")
    else:
        frame2.config(cursor="crosshair")
        message_label.config(text=f"CROSSHAIR: at x:({event.x}, y:{event.y})")

frame.bind("<Motion>", on_mouse_motion)

frame.pack(expand=True, fill="both")
frame2.pack(expand=True, fill="both")
root.mainloop()
发布评论

评论列表(0)

  1. 暂无评论