Как использовать Canvas.create_image

В настоящее время я работаю над проектом, и у меня была плохая идея до сих пор не тестировать свой код.

У меня было несколько ошибок, но здесь я выставляю только одну из них, которую я старался свести к минимуму.

Вот мой код:

from tkinter import *

root = Tk()
can = Canvas(root, height = 200, width = 300, bg = "white")
can.tab = [{} for k in range(5)]
nb = 0

def del(event):
    global can, nb
    can.tab[nb-1] = {}
    nb -= 1

def click(event):
    global can, nb
    x,y = (event.x)//50 * 50, (event.y)//50 * 50
    can.tab[nb]['image'] = PhotoImage(master = can, file = "mouse_pointer.png", name = "mouse_pointer") #Removing the name definition makes it work
    can.create_image(x, y, anchor = NW, image = can.tab[nb]['image'])
    nb += 1

can.focus_set()
can.bind("<Button-1>", click)
can.bind("<Delete>", del)

can.pack()
root.mainloop()

Цель этого кода предназначен для создания холста, на котором, когда вы щелкаете, создается изображение там, где вы щелкнули, а когда вы нажимаете del, он заставляет исчезнуть последнее созданное изображение.

Проблема в следующем Если я не даю имя своим изображениям, это работает нормально, но когда я даю им имя (тогда все они имеют одно и то же!), Когда я нажимаю del, они удаляются все, а не только последнее.

Это не очень поможет мне в продвижении моего проекта, но я хотел бы понять, что здесь происходит.

Не используйте del в качестве имени функции. del - это ключевое слово Python, которое используется для удаления ссылки на объект.

figbeam 01.05.2018 15:04

Я не уверен, почему вы даете изображениям имена, но если вы дадите им разные имена, это сработает лучше.

figbeam 01.05.2018 15:16

Я согласен, но в этом нет никакого смысла! Почему имя изменило поведение?

Léo Poirel 01.05.2018 20:16
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
6 783
1

Ответы 1

Существуют разные сценарии выполнения того, что вы ищете.

Это идея, вы можете адаптировать ее под свои нужды:

У вас я бы положился на функцию delete(), которая принимает идентификатор созданного изображения для удаления. Его также можно использовать для удаления всех существующих изображений на холсте, передав параметр all.

Чтобы решить вашу проблему, вы можете, например, сохранить идентификаторы созданных вами изображений (пять из них, я думаю) в стек (список или что-то еще, в зависимости, как я уже сказал, от вашего конкретного случая, так как ваш пример здесь довольно расплывчато для меня), а затем удалите их после LIFO:

from tkinter import *

root = Tk()
can = Canvas(root, height = 200, width = 300, bg = "white")
can.tab = [{} for k in range(5)]
nb = 0

stack_ids = [] # added this
def bell(event):
    can.delete(stack_ids.pop()) #modified your function here

def click(event):
    global can, nb
    x,y = (event.x)//50 * 50, (event.y)//50 * 50
    can.tab[nb]['image'] = PhotoImage(master = can, file = "mouse_pointer.png", name = "mouse_pointer") 
    id = can.create_image(x, y, anchor = NW, image = can.tab[nb]['image'])
    stack_ids.append(id) # save the ids somewhere


can.focus_set()
can.bind("<Button-1>", click)
can.bind("<Delete>", bell)

can.pack()
root.mainloop()

Спасибо, что ответили! Во-первых, на самом деле моя программа сама по себе не имеет никакого смысла, я просто указывал на возникшую у меня проблему и, таким образом, сократил код до минимума. Во-вторых, ваше решение решает мою проблему, но не объясняет, почему оно у меня было, что было моей основной целью. Наконец, если вы попробуете код, который вы мне предлагаете (используя изображение размером менее 50 * 50 пикселей), вы увидите, что у меня все еще есть проблема: когда я удаляю изображение, а затем пытаюсь его воссоздать, я получаю сообщение об ошибке, говорящее, что изображение не существует ...

Léo Poirel 01.05.2018 20:12

Другие вопросы по теме