Posts: 49
Threads: 16
Joined: Jun 2023
I have a single window (root):
window = customtkinter.CTk() which holds several widges as (mapview,labels,combos....).
I use this function to get mouse x and y position, while mouse is moving:
It shows coordinates, but at every widget it resets x,y values. Intention was to treat window as a whole, without resetting coordinates when mousepointer hits a widget.
Widges uses window as first parameter.
Whats the approach for the above?
(think I read that windows needs focus for events to run, so thats not an option(?)
def motion(event):
inp_posskjermx["text"] = f"{event.x}"
inp_posskjermy["text"] = f"{event.y}"
inp_posskjermx.configure(text=f"{event.x}")
inp_posskjermy.configure(text=f"{event.y}")
window.bind('<Motion>', motion)
Posts: 6,812
Threads: 20
Joined: Feb 2020
Jul-10-2023, 06:03 PM
(This post was last modified: Jul-10-2023, 06:03 PM by deanhystad.)
Are you sure this is something you want? I think I remember one of your earlier posts that included a map. Are your trying to find the mouse location in the map window? If so, the easiest way to do this is bind motion for the map only.
In this example I only bind potion events for the "position" label. Move the mouse inside the "position" label and it reports the mouse position relative to the label. Move the mouse outside the label and the motion() function is not called. I find this to be a most useful behavior since widgets generally don't care about mouse events that happen somewhere else.
The window does not need focus for the motion event to run. To verify I added an entry widget where you can type text. Press the Enter key and the text is copied to the position label. Now move the cursor over the position label and you will see the mouse position displayed. You can still type, so the entry has retained focus.
import tkinter as tk
window = tk.Tk()
def copy_entry(event):
print(event)
position["text"] = entry.get()
def motion(event):
position["text"] = f"{event.x}, {event.y}"
entry = tk.Entry(window, width=10, font=("Ariel", 24, "bold"))
entry.pack(padx=50, pady=20)
entry.bind("<Return>", copy_entry)
position = tk.Label(
window, width=10, font=("Ariel", 60, "bold")
) # Save label object in variable.
position.pack(padx=50, pady=50)
position.bind("<Motion>", motion)
window.mainloop() And if you really want to get the position of the mouse in the root window, you can ask for it.
import tkinter as tk
window = tk.Tk()
def copy_entry(event):
print(event)
position["text"] = entry.get()
def motion(event):
x, y = window.winfo_pointerxy() # Ignore the event info. Ask for the cursor position.
position["text"] = f"{x}, {y}"
entry = tk.Entry(window, width=10, font=("Ariel", 24, "bold"))
entry.pack(padx=50, pady=20)
entry.bind("<Return>", copy_entry)
position = tk.Label(
window, width=10, font=("Ariel", 60, "bold")
) # Save label object in variable.
position.pack(padx=50, pady=50)
window.bind("<Motion>", motion)
window.mainloop()
Posts: 49
Threads: 16
Joined: Jun 2023
Thanks for th info. As seeen from attached image, the map aare and several widtges (controls). All on root window, named window.
Map, https://github.com/TomSchimansky/TkinterMapView,
The map returns longitude/latitude coords when clicked, so I suppose I cant add a transparent window to hold the screen mouse movemennt event handler to avoid that controls (widtges) resets the coordinates.
I would like event report back coordinates untouced by controls.
I am thinking of adding values to reported x and y coordinates when mousepointer reach the map area, but that involves some nasty comparements :)
Ill look into your postof today tomorrow. thanks.
(Jul-10-2023, 06:03 PM)deanhystad Wrote: Are you sure this is something you want? I think I remember one of your earlier posts that included a map. Are your trying to find the mouse location in the map window? If so, the easiest way to do this is bind motion for the map only.
In this example I only bind potion events for the "position" label. Move the mouse inside the "position" label and it reports the mouse position relative to the label. Move the mouse outside the label and the motion() function is not called. I find this to be a most useful behavior since widgets generally don't care about mouse events that happen somewhere else.
The window does not need focus for the motion event to run. To verify I added an entry widget where you can type text. Press the Enter key and the text is copied to the position label. Now move the cursor over the position label and you will see the mouse position displayed. You can still type, so the entry has retained focus.
import tkinter as tk
window = tk.Tk()
def copy_entry(event):
print(event)
position["text"] = entry.get()
def motion(event):
position["text"] = f"{event.x}, {event.y}"
entry = tk.Entry(window, width=10, font=("Ariel", 24, "bold"))
entry.pack(padx=50, pady=20)
entry.bind("<Return>", copy_entry)
position = tk.Label(
window, width=10, font=("Ariel", 60, "bold")
) # Save label object in variable.
position.pack(padx=50, pady=50)
position.bind("<Motion>", motion)
window.mainloop() And if you really want to get the position of the mouse in the root window, you can ask for it.
import tkinter as tk
window = tk.Tk()
def copy_entry(event):
print(event)
position["text"] = entry.get()
def motion(event):
x, y = window.winfo_pointerxy() # Ignore the event info. Ask for the cursor position.
position["text"] = f"{x}, {y}"
entry = tk.Entry(window, width=10, font=("Ariel", 24, "bold"))
entry.pack(padx=50, pady=20)
entry.bind("<Return>", copy_entry)
position = tk.Label(
window, width=10, font=("Ariel", 60, "bold")
) # Save label object in variable.
position.pack(padx=50, pady=50)
window.bind("<Motion>", motion)
window.mainloop()
Attached Files
Thumbnail(s)
Posts: 6,812
Threads: 20
Joined: Feb 2020
Jul-11-2023, 12:10 AM
(This post was last modified: Jul-11-2023, 12:10 AM by deanhystad.)
I think it will work if you bind the map.canvas motion events.
import tkinter as tk
from tkintermapview import TkinterMapView
class MyWindow(tk.Tk):
"""A window that selects one of several pages to display."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.map = TkinterMapView(self, width=800, height=600, corner_radius=0)
self.map.pack(expand=True, fill=tk.BOTH)
self.map.set_position(60.03345, 11.35806) # Norway
self.map.set_address("fjellvegen 4, auli, norway", marker=True)
self.map.set_zoom(16)
self.map.canvas.bind("<Motion>", self.motion) # map.canvas is the window that holds the map.
self.coordinates = tk.Label(self, width=10, font=(None, 24))
self.coordinates.pack(fill=tk.X, padx=5, pady=5)
def motion(self, event):
self.coordinates.configure(text=f"{event.x}, {event.y}")
MyWindow().mainloop() Unless you need to reference something in another post, use the "New Reply" button instead of the "Reply" button. If we always use the "Replay" button it doesn't take long for posts with replies to replies to replies to replies to become unreadable.
|