Как сделать поясняющий текст справа от мышки при попадании в круги?
У меня есть программа, ниже будет код. Которая при наведении мышью на круги должна выводить около мыши поясняющий текст, как это можно реализовать? Код:
from tkinter import *
#from PIL import Image, ImageTk
#from idlelib.tooltip import Hovertip
root = Tk()
x = None
y = None
#b1 = Button(text='button with tooltip')
#b1.pack()
#Hovertip(b1, "абракадабра", hover_delay=100)
def getorigin(event):
global x, y
x = event.x # !!!
y = event.y # !!!
if (0 <= x <= 100) and (0 <= y <= 100): # !!!
print(f'Вы попали в квадрат (0, 0) - (100, 100). X = {x}, Y = {y}')
if (200 <= x <= 300) and (0 <= y <= 100): # !!!
print(f'Вы попали в квадрат (0, 0) - (100, 100). X = {x}, Y = {y}')
root.bind("<Motion>",getorigin)
#Добавим изображение
canvas = Canvas(root, height=800, width=800)
#image = Image.open("bizon.jpg")
#photo = ImageTk.PhotoImage(image)
#image = canvas.create_image(0, 0, image=photo, anchor='nw')
shar1=canvas.create_oval(0, 0, 100, 100, outline="yellow", fill="#125B50", width=2)
shar2=canvas.create_oval(200, 0, 300, 100, outline="yellow", fill="#125B50", width=2)
canvas.pack()
root.mainloop()
Ответы (1 шт):
Автор решения: insolor
→ Ссылка
Отображение подсказки через create_text при попадании мыши в ограничивающий прямоугольник нужной фигуры:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
tooltip = None
def create_tooltip(x, y, text):
global tooltip
tooltip = canvas.create_text(x, y, text=text, anchor=NW)
def delete_tooltip():
global tooltip
canvas.delete(tooltip)
tooltip = None
def on_move(event):
x1, y1, x2, y2 = canvas.bbox(oval) # Получаем координаты ограничивающего прямоугольника для овала
if (x1 <= event.x <= x2) and (y1 <= event.y <= y2):
if tooltip is None:
create_tooltip(event.x + 10, event.y + 10, "Наведено на овал")
else:
canvas.moveto(tooltip, event.x + 10, event.y + 10)
else:
delete_tooltip()
def on_leave(event):
delete_tooltip()
root.bind("<Motion>", on_move) # Событие движения мыши по холсту
root.bind("<Leave>", on_leave) # Событие перемещения мыши за пределы холста
canvas = Canvas(root, height=800, width=800)
oval=canvas.create_oval(0, 0, 100, 100, outline="yellow", fill="#125B50", width=2)
canvas.pack()
root.mainloop()
Для подсказки с фоном и рамкой можно использовать create_window с Label внутри вместо create_text:
def create_tooltip(x, y, text):
global tooltip
label = Label(text=text, justify=LEFT, background="#ffffe0", relief=SOLID, borderwidth=1)
tooltip = canvas.create_window(x, y, window=label, anchor=NW)
Дополнительно, более строгая проверка попадания указателя внутрь эллипса через уравнение эллипса (тогда подсказка будет отображаться только внутри эллипса, но не внутри всего ограничивающего прямоугольника эллипса):
def on_move(event):
x1, y1, x2, y2 = canvas.bbox(oval) # Получаем координаты ограничивающего прямоугольника для эллипса
# Координаты центра эллипса
xc = (x1 + x2) / 2
yc = (y1 + y2) / 2
# Вычисляем полуоси эллипса (сразу возводим в квадрат, потом подставляем в уравнение)
a2 = (xc - x1) ** 2
b2 = (yc - y1) ** 2
# Координаты мыши относительно центра эллипса
x = event.x - xc
y = event.y - yc
if (x ** 2 / a2 + y ** 2 / b2) <= 1:
if tooltip is None:
create_tooltip(event.x + 10, event.y + 10, "Наведено на овал")
else:
canvas.moveto(tooltip, event.x + 10, event.y + 10)
else:
delete_tooltip()
Код с проверкой на попадание в один из нескольких эллипсов:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
tooltip = None
def create_tooltip(x, y, text):
global tooltip
label = Label(text=text, justify=LEFT, background="#ffffe0", relief=SOLID, borderwidth=1)
tooltip = canvas.create_window(x, y, window=label, anchor=NW)
def delete_tooltip():
global tooltip
canvas.delete(tooltip)
tooltip = None
def in_ellipse(x, y, ellipse):
x1, y1, x2, y2 = canvas.bbox(ellipse)
# Координаты центра эллипса
xc = (x1 + x2) / 2
yc = (y1 + y2) / 2
# Вычисляем полуоси эллипса (сразу возводим в квадрат, потом подставляем в уравнение)
a2 = (xc - x1) ** 2
b2 = (yc - y1) ** 2
# Координаты мыши относительно центра эллипса
x = x - xc
y = y - yc
return (x ** 2 / a2 + y ** 2 / b2) <= 1
last_ellipse = None
def on_move(event):
global last_ellipse
for ellipse, name in ellipses.items():
if in_ellipse(event.x, event.y, ellipse):
if ellipse != last_ellipse:
delete_tooltip()
last_ellipse = ellipse
if tooltip is None:
create_tooltip(event.x + 10, event.y + 10, f"Наведено на {name}")
else:
canvas.moveto(tooltip, event.x + 10, event.y + 10)
break
else:
# Ни на что не наведено
last_ellipse = None
delete_tooltip()
def on_leave(event):
global last_ellipse
last_ellipse = None
delete_tooltip()
root.bind("<Motion>", on_move) # Событие движения мыши по холсту
root.bind("<Leave>", on_leave) # Событие перемещения мыши за пределы холста
canvas = Canvas(root, height=800, width=800)
canvas.pack()
shar1=canvas.create_oval(0, 0, 100, 100, outline="yellow", fill="#125B50", width=2)
shar2=canvas.create_oval(200, 0, 300, 100, outline="yellow", fill="#125B50", width=2)
ellipses = {
shar1: "Шар 1",
shar2: "Шар 2",
}
root.mainloop()



