Рассмотрим такой пример:
from tkinter import * from random import randrange as rnd, choice import time root = Tk() root.geometry('800x600') canv = Canvas(root,width=800,height=600,bg='white') canv.pack() def clear(event): canv.delete(ALL) colors = ['lightyellow', 'lightgray', 'gray', 'pink', 'violet', 'brown', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'magenta', 'black', 'gray', 'lightgreen'] def paint(event): clear(0) x = event.x y = event.y r = rnd(10,70) color = choice(colors) canv.create_oval(x-r,y-r,x+r,y+r,fill = color) canv.bind('<Button-1>',paint) mainloop()
Что происходит?
canv.bind('',paint)
связывает событие «Button-1», т.е. щелчок левой кнопкой мыши на Canvas и вызов функции paint, т.е. теперь paint будет вызываться не тогда, когда мы нажмем кнопку в окне, а когда мы будем щелкать мышкой в разных местах Canvas, а event.x, event.y поможет нам узнать координаты щелчка.
Измените одну строку, но не запускайте сразу. Motion – это событие, которое возникает при перемещении мыши. Как вы думаете, что произойдет? Проверьте ваше предположение, запустив программу.
canv.bind('',paint)
А теперь удалите вызов clear(0) в начале функции paint. И опять подумайте, к чему это должно привести и только потом запускайте.
Еще немного поиграем с мышью: в следующем примере слишком много нового, чтобы его было просто понять. Мы будем разбирать это позже, поэтому не переживайте, если некоторая часть кода не будет понятна. Это забавно и стоит того, чтобы попробовать прямо сейчас.
from tkinter import * from random import randrange as rnd import time root = Tk() root.geometry('800x600') canv = Canvas(root,width=800,height=550,bg='white') canv.pack() def clear(event): canv.delete(ALL) colors = ['lightyellow', 'lightgray', 'gray', 'pink', 'violet', 'brown', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'magenta', 'black', 'gray', 'lightgreen'] tail = [] def paint(event): global tail x = event.x y = event.y tail += [(x,y)] tail = tail[-20:] r = 20 clear(0) for t in tail: x = t[0] y = t[1] canv.create_oval(x-r,y-r,x+r,y+r,fill = 'lightgreen') canv.bind('<Motion>',paint) mainloop()
Черную окантовку окружности лучше убрать:
canv.create_oval(x-r,y-r,x+r,y+r,fill = 'lightgreen', width=0)
И еще один прием:
from tkinter import * from random import randrange as rnd import time root = Tk() root.geometry('800x600') canv = Canvas(root,width=800,height=550,bg='lightblue') canv.pack() def clear(event): canv.delete(ALL) colors = ['lightyellow', 'lightgray', 'gray', 'pink', 'violet', 'brown', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'magenta', 'black', 'gray', 'lightgreen'] tail = [] def paint(event): global tail x = event.x y = event.y tail += [(x,y)] tail = tail[-30:] r = 2 clear(0) for t in tail: x = t[0] y = t[1] r += 1 canv.create_oval(x-r,y-r,x+r,y+r,fill = 'yellow', width=0) canv.bind('<Motion>',paint) mainloop()
Наоборот тоже забавно:
tail = [] def paint(event): global tail x = event.x y = event.y tail += [(x,y)] tail = tail[-30:] r = 30 clear(0) for t in tail: x = t[0] y = t[1] r -= 1 canv.create_oval(x-r,y-r,x+r,y+r,fill = 'yellow', width=0)
global
? (см. справочник – область видимости)2. Что делает
tail = tail[-30:]
? (см. справочник — списки)
Если вам не нравится, что изменения на экране происходят только после того, как будет перемещена мышь, то посмотрите на другой вариант: мышь оставляет след (без задержки)
One thought on “16. Мышка оставляет след. Работаем с информацией о событии (event) в Tkinter”