Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 10, 2017 12:17:43

Aturo
Зарегистрирован: 2017-10-28
Сообщения: 24
Репутация: +  2  -
Профиль   Отправить e-mail  

вопрос по tkinter

Доброго времени, форумчане. Написал функцию, которая заполняет холст квадратами, но не пойму как поймать нажатия по ним. Т.е. при щелчке по квадрату он должен поменять цвет.

 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)
Заранее признателен всем кто поможет.

Офлайн

#2 Дек. 10, 2017 12:56:10

DamMercul
Зарегистрирован: 2017-11-26
Сообщения: 325
Репутация: +  13  -
Профиль   Отправить e-mail  

вопрос по tkinter

Биндить можно. Только зачем тебе делать квадраты. Юзай Button. У него тоже есть параметры высота-ширина. А биндить если кнопки не надо. Но если так зацепило, то:

 def lkm(event):  # не понимаю зачем тут тебе self.
    if event.keysym == "Enter":
        canv.create_rectangle["black"] = "fill"  # Менять цвет по-другому надо. Ты создаешь новый квадрат, и то не верно
root.bind("<KeyPress>", lkm)

P. S. Бинд в ткинтере работает по принципу Нажал-Сделал. Возможно сделал не по задаче. Если хочешь сделать, чтобы можно было нажать на квадрат, то надо отслеживать координаты мышки на root'е и сравнивать с коорд. квадрата



____________________________________________________

 # Life loop
while alive:
    if (fun > boredom) and money:
        pass_day(fun, boredom, money)
        continue
    else: break

Отредактировано DamMercul (Дек. 10, 2017 12:57:21)

Офлайн

#3 Дек. 10, 2017 14:09:44

Aturo
Зарегистрирован: 2017-10-28
Сообщения: 24
Репутация: +  2  -
Профиль   Отправить e-mail  

вопрос по tkinter

 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()
Попробовал сделать с кнопками, но проблема так и осталась, т.к. не знаю что писать в def click(event): чтобы поменять цвет той кнопки на которую нажал. Ищу литературу по данному вопросу, но пока нашёл только как при нажатии создать поверх другую кнопку с нужными мне параметрами.

Офлайн

#4 Дек. 10, 2017 17:52:55

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

вопрос по tkinter

Aturo
не знаю что писать в def click(event): чтобы поменять цвет той кнопки на которую нажал
ну дык event он достаточно сложный обьект.
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
например event.widget содержит виджет который являеться источнико события.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#5 Дек. 11, 2017 19:12:01

Aturo
Зарегистрирован: 2017-10-28
Сообщения: 24
Репутация: +  2  -
Профиль   Отправить e-mail  

вопрос по tkinter

Проблему решил. Оставлю свой говнокод, авось кому тоже зададут в школе/универе.

 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)

Офлайн

#6 Дек. 11, 2017 20:20:05

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

вопрос по tkinter

честно, за тако код бил бы по рукам, каждый раз раз щелкая по канвасу, вы перебираете все пикселы? + вы еще храните чтото в двух списках. + даже если вы нашли нужный вам прямоугольник вы продолжаете перебирать все пикселы. Вы серьезно?
это задание на 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)

Офлайн

#7 Дек. 11, 2017 21:32:40

Aturo
Зарегистрирован: 2017-10-28
Сообщения: 24
Репутация: +  2  -
Профиль   Отправить e-mail  

вопрос по tkinter

PEHDOM
Вы серьезно?
Дело в том, что я только начал знакомство с программированием как таковым и пока ещё полный ноль в этом, посему и код такой. Со временем, полагаю, исправлюсь. Крайне признателен за конструктивную критику, вы очень помогаете. (вдвойне благодарен за CURRENT, не знал что так можно, сильно упрощает задачу)
По поводу списков, забыл сразу написать, квадраты должны быть расположены “сеткой”. Т.е. каждый на определённом месте. При вашем варианте написания квадраты могут накладываться друг на друга, поэтому складываю координаты в список (лучше пока не придумал). Собственно задание заключается в написании игры Game of life, но с остальным попробую справиться сам, иначе так ничему и не научусь.

Офлайн

#8 Дек. 11, 2017 23:27:13

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

вопрос по tkinter

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()
ЗЫ на всякий случай дока по канвасу http://effbot.org/tkinterbook/canvas.htm



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Дек. 11, 2017 23:35:14)

Офлайн

#9 Дек. 17, 2017 15:51:18

Aturo
Зарегистрирован: 2017-10-28
Сообщения: 24
Репутация: +  2  -
Профиль   Отправить e-mail  

вопрос по tkinter

Как получить теги всех элементов на холсте?
На холсте 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)

Офлайн

#10 Дек. 18, 2017 14:35:17

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

вопрос по tkinter

Aturo
На холсте 400 эл-в с тегами ‘y’ или ‘n’. Пишу canv.gettags(all) и получаю пустой список.
gettags не принимает ALL, а itemcget принимает, но вернет результат для первого найденого элемента.И честно говоря не пойму зачем? вы вед и так знаете теги все элементов, это ‘y’ или ‘n’.
Но если так уж нужно, то ваш способ достаточно адекватный, по крайней мере другого я не знаю именно в той постановке задачи. Хотя если вам нужна проверка чтобы например на поле (не)осталось элементов с какимто одним тагом, то есть другие более простые способы.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Дек. 18, 2017 14:35:30)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version