Форум сайта python.su
Доброго времени, форумчане. Написал функцию, которая заполняет холст квадратами, но не пойму как поймать нажатия по ним. Т.е. при щелчке по квадрату он должен поменять цвет.
from tkinter import * root = Tk() root.geometry('500x600') canv = Canvas(root, width=479, height=479, bg="#111")##padx='15', pady='80') def s(): x1=0 d=24 y=0 y1=24 for i in range(20): for i in range(20): canv.create_rectangle(y,x1,y1,d, fill='#002', outline="#009") x1+=24 d+=24 y+=24 y1+=24 x1=0 d=24 s() canv.pack(side='bottom') root.mainloop()
def lkm(self): canv.create_rectangle['black']='fill' root.bind("<Button-1>", lkm)
Офлайн
Биндить можно. Только зачем тебе делать квадраты. Юзай Button. У него тоже есть параметры высота-ширина. А биндить если кнопки не надо. Но если так зацепило, то:
def lkm(event): # не понимаю зачем тут тебе self. if event.keysym == "Enter": canv.create_rectangle["black"] = "fill" # Менять цвет по-другому надо. Ты создаешь новый квадрат, и то не верно root.bind("<KeyPress>", lkm)
# Life loop while alive: if (fun > boredom) and money: pass_day(fun, boredom, money) continue else: break
Отредактировано DamMercul (Дек. 10, 2017 12:57:21)
Офлайн
from tkinter import * root = Tk() root.geometry('600x600') def s(): x1=0 y1=0 for i in range(20): for i in range(20): Button(root, command=click).place(x=x1, y=y1, width=30, height=30) x1+=30 y1+=30 x1=0 s() root.mainloop()
Офлайн
Aturoну дык event он достаточно сложный обьект.
не знаю что писать в def click(event): чтобы поменять цвет той кнопки на которую нажал
[code python][/code]
Офлайн
Проблему решил. Оставлю свой говнокод, авось кому тоже зададут в школе/универе.
from tkinter import * root = Tk() root.geometry('500x600') canv = Canvas(root, width=479, height=479, bg="white") spis = [] spis2 = [] def s(): x1=0 d=24 y=0 y1=24 for i1 in range(20): for i2 in range(20): m = y, x1, y1, d spis.append(list(m)) x1+=24 d+=24 y+=24 y1+=24 x1=0 d=24 s() def click1(event): for i in range(400): if ((event.x > spis[i][0]) and (event.x < spis[i][2])) and ( (event.y > spis[i][1]) and (event.y < spis[i][3])): canv.create_rectangle(spis[i][0],spis[i][1],spis[i][2],spis[i][3], fill='#009',outline="#009") m = spis[i][0], spis[i][1], spis[i][2], spis[i][3] spis2.append(list(m)) def click2(event): for i in range(400): if ((event.x > spis2[i][0]) and (event.x < spis2[i][2])) and ( (event.y > spis2[i][1]) and (event.y < spis2[i][3])): canv.delete(i+1) canv.pack(side='bottom') canv.bind('<Button-1>', click1) canv.bind('<Button-3>', click2) root.mainloop()
Отредактировано Aturo (Дек. 11, 2017 19:12:22)
Офлайн
честно, за тако код бил бы по рукам, каждый раз раз щелкая по канвасу, вы перебираете все пикселы? + вы еще храните чтото в двух списках. + даже если вы нашли нужный вам прямоугольник вы продолжаете перебирать все пикселы. Вы серьезно?
это задание на 10-15 строк от силы.
from tkinter import * root = Tk() root.geometry('500x600') canv = Canvas(root, width=479, height=479, bg="white") rect_size = 25 # размер квадрата def click1(event): x_pos = event.x y_pos = event.y left = rect_size//2 right = rect_size - left canv.create_rectangle(x_pos - left, y_pos - left, x_pos + right, y_pos + right, fill='#009',outline="#009") def click2(event): canv.delete(CURRENT) canv.pack(side='bottom') canv.bind('<Button-1>', click1) canv.bind('<Button-3>', click2) root.mainloop()
[code python][/code]
Отредактировано PEHDOM (Дек. 11, 2017 20:45:41)
Офлайн
PEHDOMДело в том, что я только начал знакомство с программированием как таковым и пока ещё полный ноль в этом, посему и код такой. Со временем, полагаю, исправлюсь. Крайне признателен за конструктивную критику, вы очень помогаете. (вдвойне благодарен за CURRENT, не знал что так можно, сильно упрощает задачу)
Вы серьезно?
Офлайн
Aturoэто решаеться парой строчек. Исправленый вариант, квадраты размещаються сеткой, также добавлена проверка нет ли там уже кадврата, чтобы оно не рисовало один поверх другого :
По поводу списков, забыл сразу написать, квадраты должны быть расположены “сеткой”. Т.е. каждый на определённом месте. При вашем варианте написания квадраты могут накладываться друг на друга, поэтому складываю координаты в список (лучше пока не придумал)
from tkinter import * root = Tk() root.geometry('500x600') canv = Canvas(root, width=479, height=479, bg="white") rect_size = 24 # размер квадрата def click1(event): if canv.find_withtag(CURRENT): # проверка, есть ли там уже виджет return x_pos = event.x y_pos = event.y x1 = x_pos-x_pos%rect_size y1 = y_pos-y_pos%rect_size canv.create_rectangle(x1, y1, x1 + rect_size, y1 + rect_size, fill='#009',outline="#009") def click2(event): canv.delete(CURRENT) canv.pack(side='bottom') canv.bind('<Button-1>', click1) canv.bind('<Button-3>', click2) root.mainloop()
[code python][/code]
Отредактировано PEHDOM (Дек. 11, 2017 23:35:14)
Офлайн
Как получить теги всех элементов на холсте?
На холсте 400 эл-в с тегами ‘y’ или ‘n’. Пишу
canv.gettags(all)
z = [] all1 = canv.find_all() for lk in all1: z1 = canv.gettags(lk) z.append(z1)
Отредактировано Aturo (Дек. 17, 2017 16:16:45)
Офлайн
Aturogettags не принимает ALL, а itemcget принимает, но вернет результат для первого найденого элемента.И честно говоря не пойму зачем? вы вед и так знаете теги все элементов, это ‘y’ или ‘n’.
На холсте 400 эл-в с тегами ‘y’ или ‘n’. Пишу canv.gettags(all) и получаю пустой список.
[code python][/code]
Отредактировано PEHDOM (Дек. 18, 2017 14:35:30)
Офлайн