Нарисуйте три кораблика
Вы можете себе сильно упростить жизнь при рисовании сложных объектов если начнете использовать функции.
Допустим я рисую некоторую комбинацию фигур:
from tkinter import *
root = Tk()
root.title("Я приложение =)")
canvas = Canvas(root, width=500, height=200, bg="white")
canvas.pack()
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
root.mainloop()
и мне допустим надо нарисовать еще одну такую же комбинацию, но у уже в другом месте.
Я б мог, например, взять и скопировать код, но уже с другими координатами
# старый код
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
# а тут повторил код, но сдвинул все на 70px
canvas.create_rectangle(100, 100, 170, 190, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(130, 130, 160, 160, fill="#FF0000", outline="", width=5)
и вот уже два одинаковых объекта
и вроде все ок, но если мне надо нарисовать десяток объектов или у объекта сильно много примитивных фигур внутри, то вот этот пересчет становится сильно накладным. Его долго и неудобно считать.
Намного удобнее создать свою собственную функцию в которой будут вызываться команда, делается это так:
from tkinter import *
root = Tk()
root.title("Я приложение =)")
canvas = Canvas(root, width=500, height=200, bg="white")
canvas.pack()
# добавил функцию
def draw_object():
# внутри вызываются команды
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
# А ЭТО вообще уберем
# canvas.create_rectangle(100, 100, 170, 190, fill="#ffd000", outline="#FF0000", width=5)
# canvas.create_oval(130, 130, 160, 160, fill="#FF0000", outline="", width=5)
root.mainloop()
запустим:
хм, ничего не вывелось. А ну да! Надо ведь вызвать нашу функцию.
# ...
canvas.pack()
def draw_object():
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
# вызываем нашу функцию, для этого пишем ее имя вместе со скобочками
draw_object()
root.mainloop()
проверяем
О! Красота! =)
А как бы теперь нарисовать второй объект?
Попробуем вызвать функцию два раза:
# ...
def draw_object():
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
draw_object()
draw_object() # добавил второй вызов
root.mainloop()
тестим:
так, ничего не поменялось. Но это в принципе логично, так как по сути один объект нарисовался поверх другого.
Нам надо как-то реализовать возможность сдвигать объект.
Для этого нам пригодится возможность добавлять к функции параметры.
Давайте добавим два параметра нашей функции. Сдвиг по оси X и сдвиг по оси Y
# ...
canvas.pack()
# добавил параметры
def draw_object(x, y):
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
draw_object()
draw_object()
root.mainloop()
теперь кстатит если запустить программу она вообще не сработает:
то есть так как мы добавили два аргумента нашей функции, то вызывая ее надо в эти аргументы что-то передавать
# ...
canvas.pack()
def draw_object(x, y):
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
# добавил аргументы
draw_object(0, 0)
draw_object(150, 10)
root.mainloop()
запускаем:
все еще ничего не поменялось. Как так?
Дело в том, что несмотря на то что мы добавили два аргумента нашей функции
def draw_object(x, y):
canvas.create_rectangle(30, 30, 100, 120, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60, 60, 90, 90, fill="#FF0000", outline="", width=5)
мы их при последующем выводе никак не используем. Давайте задействуем эти самые x и y при выводе.
То есть так как они отвечают за сдвиг по осям X и Y соответственно, значит надо просто добавлять эти x и y к координатам при отрисовке, вот так:
def draw_object(x, y):
canvas.create_rectangle(30 + x, 30 + y, 100 + x, 120 + y, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60 + x, 60 + y, 90 + x, 90 + y, fill="#FF0000", outline="", width=5)
попробуем еще раз запустить:
Ура! Сработало! =О
То есть как это работает. Если у нас есть такой код:
def draw_object(x, y):
canvas.create_rectangle(30 + x, 30 + y, 100 + x, 120 + y, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60 + x, 60 + y, 90 + x, 90 + y, fill="#FF0000", outline="", width=5)
draw_object(0, 0)
draw_object(150, 10)
то при выполнении программы он превращается в некий аналог такого кода:
# для draw_object(0, 0) получается
canvas.create_rectangle(30 + 0, 30 + 0, 100 + 0, 120 + 0, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60 + 0, 60 + 0, 90 + 0, 90 + 0, fill="#FF0000", outline="", width=5)
# для draw_object(150, 10) выходит:
canvas.create_rectangle(30 + 150, 30 + 10, 100 + 150, 120 + 10, fill="#ffd000", outline="#FF0000", width=5)
canvas.create_oval(60 + 150, 60 + 10, 90 + 150, 90 + 10, fill="#FF0000", outline="", width=5)
ну и согласитесь что написать draw_object(0, 0) намного приятнее чем прописывать все команды и все сдвиги вручную.
Ну все, вы подкреплены знаниями, гоу пилить задание =)