#python #tkinter
#python #tkinter
Вопрос:
Я пытаюсь создать базовую игру в Tkinter, которая включает в себя нажатие кнопки «Пуск» и отображение фигуры, которая работает, затем, когда вы нажимаете на фигуру, она удаляется и перемещается в другое случайное место.
Я получаю NameError: name 'square' is not defined
, когда пытаюсь его запустить.
root=Tk()
frame=Frame(root)
can = Canvas(root, width=400, height=400)
can.pack(side=TOP)
def makeShape():
xpos = random.randint(1, 400)
ypos = random.randint(1, 400)
square=can.create_polygon(xpos, ypos, xpos 40, ypos, xpos 40, ypos 40,
xpos, ypos 40, fill="blue")
can.tag_bind(square,"<Button-1>",deleteShape)
def deleteShape(event):
can.delete(square)
but1 = Button(frame, text="Start", command=makeShape)
but1.grid(row=1, column=2)
frame.pack(side=BOTTOM)
root.mainloop()
Комментарии:
1. Зачем удалять и создавать заново? На холсте есть способы перемещения объекта.
2. @BryanOakley возможно, это было бы проще, но я боролся с перемещением из-за случайных координат
3. Майк: Случайные координаты не должны быть проблемой, потому что при перемещении элемента Canvas все, что вам нужно указать, это суммы для перемещения в направлениях x и y (и тег или идентификатор объекта).).
4. @martineau итак, должен ли я сделать его похожим на приведенный выше код makeShape, но заменить create на move, или это приведет к перемещению фигуры с холста или аналогичной ошибке?
5. Пожалуйста, не вандализируйте свои посты. После того, как вы отправили сообщение, вы лицензировали контент сообществу Stack Overflow в целом ( по лицензии CC BY-SA ). Согласно политике SE, любой вандализм будет отменен.
Ответ №1:
Это потому square
, что это локальная переменная внутри makeShape()
, поэтому к ней нельзя получить доступ вне функции.
Вместо этого вы можете использовать tags
option in create_polygon()
. Если вы хотите переместить квадрат при нажатии на него, deleteShape()
в этом нет никакой необходимости. Достаточно просто использовать makeShape()
:
from tkinter import *
import random
root=Tk()
frame=Frame(root)
can = Canvas(root, width=400, height=400)
can.pack(side=TOP)
def makeShape():
# delete existing square
can.delete("square")
# create square at random position
xpos = random.randint(1, 360)
ypos = random.randint(1, 360)
can.create_polygon(xpos, ypos, xpos 40, ypos, xpos 40, ypos 40, xpos, ypos 40,
fill="blue", tags="square")
# call makeShape() when the square is clicked
can.tag_bind("square", "<Button-1>", lambda e: makeShape())
but1 = Button(frame, text="Start", command=makeShape)
but1.grid(row=1, column=2)
frame.pack(side=BOTTOM)
root.mainloop()
Комментарии:
1. @Mike: Это решение лучше в том смысле, что оно не требует использования глобальной переменной (хотя само имя тега, вероятно, следует сделать глобальной константой ).
Ответ №2:
Хотя это не очень хорошая практика, если вы добавите к ней строку global square
makeShape()
, она будет работать так, как ожидалось.
Это связано с тем, что если имя присваивается в первый раз внутри блока, оно не будет видно родительским или родственным блокам.
Существуют альтернативы, которые считаются лучшими для удобства чтения и более практичными, но мое предложение — это самое быстрое решение вашей проблемы.
Комментарии:
1. Хорошо, спасибо, просто из интереса, что бы вы предложили, чтобы улучшить его читаемость?
2. @Mike: Если вы удалите фигуру, вы не сможете ее переместить (очевидно). Простое создание
square
глобальной переменной не повлияет на возможность ее перемещения в противном случае.