#python #tkinter
Вопрос:
class Right(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master.bind('<Enter>',self.mouse)
self.master.bind('<Leave>',self.inmouse)
self.lbl_77 = Label(self, text= 'Hellow', bg= 'green', fg='black')
def mouse(self, event):
self.lbl_77 .place(x=90, y=0)
def inmouse(self, event):
self.lbl_77 .place_forget()
root = Tk()
frame = Right(root)
root.mainloop()
Что я попытался сделать с помощью кода, приведенного выше, так это сделать метку с сообщением «привет» видимой только тогда, когда указатель мыши находится на окне, и удалить ее, когда она его покидает. Мой вопрос в том, могу ли я разграничить область, которую нужно разделить на окно, так, чтобы только в том случае, если она лежит на нем, активировалось событие отображения метки.
Ответ №1:
Итак, вот подход, он использует <Motion>
событие для отслеживания движения мыши, а также возвращает объект движения, который имеет атрибуты x
и y
который позволяет определить, где в данный момент находится мышь:
self.master.bind('<Motion>', self.mouse)
self.lbl_77 = Label(self, text='Hellow', bg='green', fg='black')
def mouse(self, event):
x, y = event.x, event.y
x1, x2 = 0, 50
y1, y2 = 0, 50
if x1 < x < x2 and y1 < y < y2:
self.lbl_77.place(x=90, y=0)
else:
self.lbl_77.place_forget()
Тогда дело в том, чтобы просто установить границы того, где проверять наличие мыши, и использовать простую if statement
. Полный код будет выглядеть следующим образом:
from tkinter import Tk, Frame, Label
class Right(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master.bind('<Motion>', self.mouse)
self.lbl_77 = Label(self, text='Hellow', bg='green', fg='black')
def mouse(self, event):
x, y = event.x, event.y
x1, x2 = 0, 50
y1, y2 = 0, 50
if x1 < x < x2 and y1 < y < y2:
self.lbl_77.place(x=90, y=0)
else:
self.lbl_77.place_forget()
root = Tk()
root.geometry('500x500')
frame = Right(root)
frame.pack(fill='both', expand=True)
root.mainloop()
Несколько других деталей-это .pack()
(или .grid()
) рамка, чтобы она расширилась и заполнила максимальную площадь (потому что вы используете .place()
), также, вероятно, установите геометрию окна на что-то, чтобы вам не пришлось изменять размер самостоятельно.
Импорт предложение:
я настоятельно не рекомендуем использовать подстановочный знак ( *
) при импорте что-то, вы должны либо импортировать то, что вам нужно, например, from module import Class1, func_1, var_2
и так далее, либо импортировать весь модуль: import module
вы также можете использовать псевдоним: import module as md
или sth, как это, дело в том, что не все импортное, если вы на самом деле знаете, что Вы делаете; наименование столкновения эту проблему.
Предложение PEP 8:
Я настоятельно рекомендую следовать руководству по стилю PEP 8 для кода Python. Имена функций и переменных должны быть в snake_case
, имена классов в CapitalCase
. Не используйте пробел, =
если он используется как часть аргумента ключевого слова ( func(arg='value')
), но используйте пробел, =
если он используется для присвоения значения ( variable = 'some value'
). Есть пространство вокруг операторов ( -/
и т.д.: value = x y
(кроме здесь value = x y
)). Есть две пустые строки вокруг объявлений функций и классов.
Комментарии:
1. Спасибо вам за ваш ответ и предложение. Ваш ответ разрешил вопрос, который я задал. Хотя код четко определен, он приносит с собой новые вопросы. Я надеюсь, что кто-нибудь сможет мне ответить. Спасибо.
<Motion>
проблема решена, но при быстром удалении указателя мыши из окна (область активации) метка все еще видна.2. Мне приходит в голову использовать функцию:
after
и` DoubleVar` для обновления event.x , но она плохо работаетself.master.bind ('<Button-1>', self.return)
, потомуdef return (self )
что постоянно позиционирует метку при нажатии на ту же область триггераevent.x
, и, похоже, возникает конфликт междуevent.x
и` self.return`. потому что этикетка мигает3. Я понимаю, что метка останется, если вы быстро переместите курсор полностью за пределы окна? Хорошо привяжите
'<Leave>'
событие, которое будет просто.place_forget()
self
:self.bind('<Leave>', lamda e: self.lbl_77.place_forget())
4. Это отлично сработало, спасибо. Привязка
<Leave>
события к рамке, а не к родительскому окну работала нормально.