Как изменить цвет линии tkinter

Рисуем линии, треугольники, прямоугольники и многоугольники в Tkinter. Меняем цвет для фигур и меняем шрифт текста.

В этой части изучения Tkinter мы немного порисуем. Рисование в Tkinter реализовано при помощи виджета Canvas. Это функционал высокого уровня, который позволяет создавать графику в Tkinter. Рисование можно использовать для создания графиков статистики, самодельных пользовательских виджетов и даже небольших игр.

Содержание курса

  1. Создание окна по центру и кнопка выхода в Tkinter
  2. Разметка виджетов в Tkinter — pack, grid и place
  3. Виджеты Checkbutton, Label, Scale и Listbox в Tkinter
  4. Меню, подменю и панель инструментов в Tkinter
  5. Диалоговые окна в Tkinter — Выбор цвета — Выбор файла
  6. Рисуем линии, прямоугольники, круг и текст в Tkinter
  7. Пишем игру змейка на Tkinter

Содержание статьи

  • Рисуем линии в Tkinter — create_line()
  • Создаем цветные прямоугольники в Tkinter
  • Рисуем различные формы в Tkinter
  • Вставляем изображение в Canvas
  • Меняем шрифт и рисуем текст в Tkinter

Рисуем линии в Tkinter — create_line()

Линия – это примитивный геометрический элемент. На виджете Canvas создать линию можно при помощи метода create_line().

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.master.title(«Рисуем линии»)

        self.pack(fill=BOTH, expand=1)

        canvas = Canvas(self)

        canvas.create_line(15, 25, 200, 25)

        canvas.create_line(300, 35, 300, 200, dash=(4, 2))

        canvas.create_line(55, 85, 155, 85, 105, 180, 55, 85)

        canvas.pack(fill=BOTH, expand=1)

def main():

    root = Tk()

    ex = Example()

    root.geometry(«400×250+300+300»)

    root.mainloop()

if __name__ == ‘__main__’:

    main()

В примере нашего кода, мы рисуем простые линии в Tkinter.

canvas.create_line(15, 25, 200, 25)

Параметрами метода create_line() являются координаты x и y, которые обозначают стартовые и конечные точки линии.

canvas.create_line(300, 35, 300, 200, dash=(4, 2))

Мы нарисовали вертикальную линию. Опция dash позволяет создать пунктированную линию. Множества (4, 3) означает:

  • 4 — длинна тире или точки в пикселях;
  • 2 — пустой промежуток между тире либо точками.

Если указать dash=(1, 1) то у нас будет линия из точек.

canvas.create_line(55, 85, 155, 85, 105, 180, 55, 85)

Метод create_line() может содержать несколько конечных точек, которые будут пресекаться линией. Согласно этому коду мы нарисовали треугольник имея три координата разных точек.

Рисуем линии в Tkinter

Цвет является объектом, который отображает комбинацию Красного, Зеленого и Синего цветов (RGB).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.master.title(«Цвета»)

        self.pack(fill=BOTH, expand=1)

        canvas = Canvas(self)

        canvas.create_rectangle(

            30, 10, 120, 80,

            outline=«#fb0», fill=«#fb0»

        )

        canvas.create_rectangle(

            150, 10, 240, 80,

            outline=«#f50», fill=«#f50»

        )

        canvas.create_rectangle(

            270, 10, 370, 80,

            outline=«#05f», fill=«#05f»

        )

        canvas.pack(fill=BOTH, expand=1)

def main():

    root = Tk()

    ex = Example()

    root.geometry(«400×100+300+300»)

    root.mainloop()

if __name__ == ‘__main__’:

    main()

В данном примере мы нарисовали прямоугольники и закрасили их разными цветами. Мы ранее работали с выбором цвета в Tkinter используя диалоговое окно цветовой палитры.

Мы создали виджет canvas.

canvas.create_rectangle(

    30, 10, 120, 80,

    outline=«#fb0», fill=«#fb0»

)

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

С помощью create_rectangle() мы создаем прямоугольник на холсте. Первыми четырьмя параметрами являются x и y координаты двух ограничительных точек: верхней левой и нижней правой. При помощи параметра outline мы можем задать цвет контура прямоугольников. А параметр fill используется для окрашивания всей внутренней области прямоугольника.

Рисуем прямоугольники в Tkinter

Рисуем различные формы в Tkinter

На холсте мы можем нарисовать самые разнообразные формы. На представленном ниже примере показаны некоторые из них.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.master.title(«Рисуем формы»)

        self.pack(fill=BOTH, expand=1)

        canvas = Canvas(self)

        # Овальная форма.

        canvas.create_oval(

            10, 10, 80, 80, outline=«#f11»,

            fill=«#1f1», width=2

        )

        # Овальная форма.

        canvas.create_oval(

            110, 10, 210, 80, outline=«#f11»,

            fill=«#1f1», width=2

        )

        # Рисуем прямоугольник.

        canvas.create_rectangle(

            230, 10, 290, 60,

            outline=«#f11», fill=«#1f1», width=2

        )

        # Рисуем дугу.

        canvas.create_arc(

            30, 200, 90, 100, start=0,

            extent=210, outline=«#f11», fill=«#1f1», width=2

        )

        points = [

            150, 100, 200, 120, 240, 180, 210,

            200, 150, 150, 100, 200

        ]

        # Рисуем многоугольник.

        canvas.create_polygon(points, outline=‘#f11’,

            fill=‘#1f1’, width=2)

        canvas.pack(fill=BOTH, expand=1)

def main():

    root = Tk()

    ex = Example()

    root.geometry(«330×220+300+300»)

    root.mainloop()

if __name__ == ‘__main__’:

    main()

Мы нарисовали разные формы в окне:

  • круг;
  • овал;
  • прямоугольник;
  • дугу и многугольник.

Контур окрашен в красный цвет, фигуры были наполнены зеленым цветом. Ширина контура указана в 2 пикселя.

canvas.create_oval(

    10, 10, 80, 80, outline=«red»,

    fill=«green», width=2

)

Метод create_oval() используется для того, чтобы создать круг в Tkinter. Первые четыре параметра определяют ограничивающие координаты фигуры. Иными словами, это x и y координаты верхней левой и правой нижней точек квадрата, в который помещен круг.

canvas.create_rectangle(

    230, 10, 290, 60,

    outline=«#f11», fill=«#1f1», width=2

)

Мы нарисовали прямоугольник в Tkinter. Координаты снова обозначают ограничительные точки с координатами x и y..

canvas.create_arc(

    30, 200, 90, 100, start=0,

    extent=210, outline=«#f11», fill=«#1f1», width=2

)

С помощью этого кода мы создаем дугу. Дуга является частью круга. Мы указывает ограничительные координаты нашей дуги.

Успейте заказать просмотры на видео в YouTube ДокторСмм по наиболее дешевой цене с большими оптовыми скидками. Кроме того, с заказом Вы сможете получить также персональные условия на приобретение ресурса с возможностью выбора более подходящей для Вашей ситуации скорости поступления просмотров. Торопитесь, скидки действуют ограниченное время!

С помощью параметра start мы устанавливаем угол дуги. Параметр extent указывает на размер угла.

points = [

    150, 100, 200, 120, 240, 180, 210,

    200, 150, 150, 100, 200

]

canvas.create_polygon(

    points, outline=‘red’,

    fill=‘green’, width=2

)

Данный код позволяет нам создать многоугольник. У этой фигуры присутствует большое количество углов. Чтобы создать многоугольник в Tkinter, нам нужно задать несколько координат, используя метод create_polygon().

Создание форм в Tkinter

Вставляем изображение в Canvas

В данном примере мы рассмотрим, как вставить изображение в canvas виджете.

В данном примере используется файл изображения tatras.jpg который нужно сохранить рядом с нами кодом:

  • tatras.jpg

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

from tkinter import Tk, Canvas, Frame, BOTH, NW

from PIL import Image, ImageTk

class Example(Frame):

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.master.title(«Изображение в Canvas»)

        self.pack(fill=BOTH, expand=1)

        self.img = Image.open(«tatras.jpg»)

        self.tatras = ImageTk.PhotoImage(self.img)

        canvas = Canvas(

            self, width=self.img.size[0]+20,

            height=self.img.size[1]+20

        )

        canvas.create_image(10, 10, anchor=NW, image=self.tatras)

        canvas.pack(fill=BOTH, expand=1)

def main():

    root = Tk()

    ex = Example()

    root.mainloop()

if __name__ == ‘__main__’:

    main()

В примере продемонстрировано как добавить изображение в Canvas.

self.img = Image.open(«tatras.jpg»)

self.tatras = ImageTk.PhotoImage(self.img)

Из библиотеки Pillow мы используем модули Image и ImageTk.

canvas = Canvas(

    self, width=self.img.size[0]+20,

    height=self.img.size[1]+20

)

Мы создаем виджет Canvas. Учитываем размеры изображения. Холст будет на 20 пикселей шире и на 20 пикселей выше, нежели наше изображение.

canvas.create_image(10, 10, anchor=NW, image=self.tatras)

Мы используем метод create_image(), чтобы создать изображение на холсте. Чтобы показать изображение, оно закрепляется в северном и западном направлениях anchor=NW нашего окна. Параметр image позволяет отобразить изображение.

Canvas Image

Меняем шрифт и рисуем текст в Tkinter

В последнем примере мы рассмотрим рисование текста используя виджет Canvas в Tkinter.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

from tkinter import Tk, Canvas, Frame, BOTH, W

class Example(Frame):

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.master.title(«Текст и Шрифт в Tkinter»)

        self.pack(fill=BOTH, expand=1)

        canvas = Canvas(self)

        canvas.create_text(

            20, 30, anchor=W, font=«DejavuSansLight»,

            text=«Красное солнце сгорает дотла»

        )

        canvas.create_text(

            20, 60, anchor=W, font=«Arial»,

            text=«На пылающий город падает тень»

        )

        canvas.create_text(

            20, 130, anchor=W, font=«TimesNewRoman»,

            text=«Перемен!»

        )

        canvas.create_text(

            20, 160, anchor=W, font=«ComicSans»,

            text=«Требуют наши сердца»

        )

        canvas.create_text(

            20, 190, anchor=W, font=«FreeSerif»,

            text=«Перемен!»

        )

        canvas.create_text(

            20, 220, anchor=W, font=«LatoThin»,

            text=«Требуют наши глаза»

        )

        canvas.pack(fill=BOTH, expand=1)

def main():

    root = Tk()

    ex = Example()

    root.geometry(«420×250+300+300»)

    root.mainloop()

if __name__ == ‘__main__’:

    main()

Мы рисуем слова из песни в нашем окне.

canvas.create_text(

    20, 30, anchor=W, font=«DejavuSansLight»,

    text=«Красное солнце сгорает дотла»

)

Первые два параметра – это x и y координаты центральной точки текста. Если мы закрепим текстовый объект по направлению запада anchor=W, текст будет начинаться в этой части окна. Параметр font позволяет нам менять шрифт текста, а параметр text отображает написанный текст в окне.

Рисуем линии, прямоугольники, круг и текст в Tkinter [Урок №6]

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: vasile.buldumac@ati.utm.md

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Asked
7 years, 9 months ago

Viewed
26k times

I draw a rectangle on a Canvas:

 canvas = Canvas(parent,  cursor="cross")   
 rect = canvas.create_rectangle(20,20, 1, 1, fill="")

I only want to draw the border, leaving the interior transparent (that is why I set fill="" as mentioned here).

My problem:

I want the rectangle to have a red border. How can I do that?

martineau's user avatar

martineau

117k25 gold badges161 silver badges290 bronze badges

asked Apr 22, 2015 at 10:33

By default, the interior of a rectangle is empty, and you can also get this
behavior with fill='' rather than just leaving it out.

If you want the rectangle outlined, just add a keyword argument named outline to the create_rectangle() call:

rect = canvas.create_rectangle(20,20, 1, 1, outline='red')

You can also control the width of the border by also adding a width=xxx keyword argument to the call. The default width is 1 pixel.

answered Apr 22, 2015 at 10:48

martineau's user avatar

martineaumartineau

117k25 gold badges161 silver badges290 bronze badges

1

From the page you linked:

outline=
Outline color. Default is “black”.

answered Apr 22, 2015 at 10:47

fhdrsdg's user avatar

fhdrsdgfhdrsdg

10k2 gold badges39 silver badges61 bronze badges

2

Последнее обновление: 25.09.2022

Удаление элемента

Для удаления применяется метод delete(), который в качестве параметра принимает идентификатор удаляемого элемента.

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("METANIT.COM")
root.geometry("300x250")

canvas = Canvas(bg="white", width=250, height=200)
canvas.pack(anchor=CENTER, expand=1)


def remove_button():
    canvas.delete(btnId)

btn = ttk.Button(text="Click", command=remove_button)
btnId = canvas.create_window(10, 20, anchor=NW, window=btn, width=100, height=50)

root.mainloop()

Здесь по нажатию на кнопку удаляется сама кнопка. В качестве аргумента в метод delete() передается идентификатор, который мы получаем при добавлении кнопки.

Управление координатами

Для получения/изменения координат элеимента применяется метод coords():

# получение координат
coords(__tagOrId: str | _CanvasItemId, /) -> list[float]     

# изменение координат
coords(__tagOrId: str | _CanvasItemId, __args: list[int] | list[float] | tuple[float, ...], /) -> None
coords(__tagOrId: str | _CanvasItemId, __x1: float, __y1: float, *args: float) -> None

Первая версия возвращает координаты в виде списка значений для элемента с определенным идентификатором.

Вторая и третья версии изменяют позицию, получая в качестве второго/третьего параметра(ов) новые координаты.

Например, динамически изменим координаты:

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("METANIT.COM")
root.geometry("300x250")

y = 0
direction = -10
btn_height = 40
canvas_height = 200

canvas = Canvas(bg="white", width=250, height=canvas_height)
canvas.pack(anchor=CENTER, expand=1)

def cliked_button():
    global y, direction
    if y >= canvas_height - btn_height or y <=0: direction = direction * -1
    y = y + direction
    canvas.coords(btnId, 10, y)

btn = ttk.Button(text="Click", command=cliked_button)
btnId = canvas.create_window(10, y, anchor=NW, window=btn, width=100, height=btn_height)

root.mainloop()

Здесь по нажатию на кнопку к координате y добавляется +-10. Когда кнопка достигает границ Canvas, то изменяем знак приращения на противоположный, и таким образом, кнопка изменяет направление движения.

Изменение параметров элемента

Для изменения параметров элемента на Canvas применяется метод itemconfigure(). В качестве обязательного параметра он принимает идентифкатор изменяемого элемента,
а второй параметр — набор устанавливаемых параметров:

itemconfigure: (tagOrId: str | _CanvasItemId, cnf: dict[str, Any] | None = ..., **kw: Any)

Например, изменим цвет линии:

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("METANIT.COM")
root.geometry("300x250")

red = "red"
blue= "blue"

selected_color = StringVar(value=red)

canvas = Canvas(bg="white", width=250, height=150)
canvas.pack(anchor=CENTER, expand=1)

def select():
    canvas.itemconfigure(line, fill=selected_color.get())

red_btn = ttk.Radiobutton(text=red, value=red, variable=selected_color, command=select, padding=6)
red_btn.pack(anchor=NW)
blue_btn = ttk.Radiobutton(text=blue, value=blue, variable=selected_color, command=select, padding=6)
blue_btn.pack(anchor=NW)

line = canvas.create_line(10, 10, 200, 100, fill=selected_color.get())

root.mainloop()

В данном случае в окне определены два переключателя Radiobutton. Они привязаны к переменной selected_color, которая хранит выбранный цвет — «red» или «blue».

На canvas нарисована линия. При нажатии на один из переключателей изменяем цвет линии:

itemconfigure и изменение параметров элементов в Canvas в Tkinter и Python

Скачайте код уроков с GitLab: https://gitlab.com/PythonRu/tkinter-uroki

В предыдущих материалах основное внимание было уделено стандартному виджету Tkinter. Однако вне внимания остался виджет Canvas. Причина в том, что он предоставляет массу графических возможностей и заслуживает отдельного рассмотрения.

Canvas (полотно) — это прямоугольная область, в которой можно выводить не только текст или геометрические фигуры, такие как линии, прямоугольники или овалы, но также другие виджеты Tkinter. Все вложенные объекты называются элементами Canvas, и у каждого есть свой идентификатор, с помощью которого ими можно манипулировать еще до момента отображения.

Рассмотрим методы класса Canvas на реальных примерах, что поможет познакомиться с распространенными паттернами, которые в дальнейшем помогут при создании приложений.

Понимание системы координат

Для рисования графических элементов на полотне, нужно обозначать их положение с помощью системы координат. Поскольку Canvas — это двумерная область, то точки будут обозначаться координатами горизонтальной и вертикальной осей — традиционными x и y соответственно.

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

Следующая программа содержит пустое полотно, а также метку, которая показывает положение курсора на нем. Можно перемещать курсор и видеть, в каком положении он находится. Это явно показывает, как изменяются координаты x и y в зависимости от положения курсора:


import tkinter as tk

class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Базовый canvas")

self.canvas = tk.Canvas(self, bg="white")
self.label = tk.Label(self)
self.canvas.bind("

", self.mouse_motion)

self.canvas.pack()
self.label.pack()

def mouse_motion(self, event):
x, y = event.x, event.y
text = "Позиция курсора: ({}, {})".format(x, y)
self.label.config(text=text)

if __name__ == "__main__":
app = App()
app.mainloop()

Как работает система координат

Экземпляр Canvas создается по аналогии с любым другим виджетом Tkinter. В него передаются родительский контейнер, а также все настройки в виде ключевых слов:


def __init__(self):
# ...
self.canvas = tk.Canvas(self, bg="white")
self.label = tk.Label(self)
self.canvas.bind("", self.mouse_motion)

Следующий скриншот показывает точку, составленную из перпендикулярных проекций двух осей:

  • Координата x соответствует расстоянию по горизонтальной оси и увеличивается по мере движения слева направо;
  • Координата y соответствует расстоянию по вертикальной оси и увеличивается по мере движения снизу вверх;
Canvas, рисование графики ч.1 / tkinter 18

Можно обратить внимание на то, что эти координаты точно соответствуют атрибутам x и y экземпляра event, который был передан обработчику:


def mouse_motion(self, event):
x, y = event.x, event.y
text = "Позиция курсора: ({}, {})".format(x, y)
self.label.config(text=text)

Так происходит из-за того, что атрибуты рассчитываются относительно виджета, к которому прикреплено событие — в этом случае это последовательность .

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

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

Рисование линий и стрелок

Одно из базовых действий, которое можно выполнить на полотне — рисование сегментов от одной точки к другой. Хотя есть другие способы рисовать многоугольники, метод create_line класса Canvas предлагает достаточное количество опций для понимания основ отображения элементов.

В этом примере создадим приложение, которое позволит рисовать линии с помощью кликов по полотну. Каждая из них будет отображаться после двух кликов: первый будет указывать на начало линии, а второй — на ее конец.

Также можно будет задавать определенные элементы внешнего вида, например, толщину и цвет:

Рисование линий и стрелок

Класс App будет отвечать за создание пустого полотна и обработку кликов мышью.

Информация о линии будет идти из класса LineForm. Такой подход с выделением компонента в отдельный класс позволит абстрагировать детали его реализации и сфокусироваться на работе с виджетом Canvas.

Говоря простым словами, мы пропускаем реализацию класса LineForm в следующем коде:


import tkinter as tk class LineForm(tk.LabelFrame):
# ...

class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Базовый canvas")
self.line_start = None
self.form = LineForm(self)
self.canvas = tk.Canvas(self, bg="white")
self.canvas.bind("

", self.draw)

self.form.pack(side=tk.LEFT, padx=10, pady=10)
self.canvas.pack(side=tk.LEFT)

def draw(self, event):
x, y = event.x, event.y
if not self.line_start:
self.line_start = (x, y)
else:
x_origin, y_origin = self.line_start
self.line_start = None
line = (x_origin, y_origin, x, y)
arrow = self.form.get_arrow()
color = self.form.get_color()
width = self.form.get_width()
self.canvas.create_line(*line, arrow=arrow,
fill=color, width=width)

if __name__ == "__main__":
app = App()
app.mainloop()

Весь код целиком можно найти в отдельном файле lesson_18/drawing.py.

Как рисовать линии в Tkinter

Поскольку нужно обрабатывать клики мышью на полотне, свяжем метод draw() с этим типом события. Также определим поле line_start, чтобы отслеживать начальное положение каждой линии:


def __init__(self):
# ...
self.line_start = None
self.form = LineForm(self)
self.canvas = tk.Canvas(self, bg="white")
self.canvas.bind("", self.draw)

Метод draw() содержит основную логику приложения. Первый клик служит для определения начала для каждой линии и ничего не рисует. Координаты он получает из объекта event, который передается обработчику:


def draw(self, event):
x, y = event.x, event.y
if not self.line_start:
self.line_start = (x, y)
else:
# ...

Если у line_start уже есть значение, то мы получаем его и передаем координаты текущего события, чтобы нарисовать линию:


def draw(self, event):
x, y = event.x, event.y
if not self.line_start:
# ...
else:
x_origin, y_origin = self.line_start
self.line_start = None
line = (x_origin, y_origin, x, y)
self.canvas.create_line(*line)
text = "Линия проведена из ({}, {}) к ({}, {})".format(*line)

Метод canvas.create_line() принимает четыре аргумента, где первые два — это горизонтальная и вертикальная координаты начала линии, а вторые два — ее конечной точки.

В некоторых случаях появляется необходимость вывести на полотне текст. Для этого нет нужды использовать дополнительный виджет, такой как Label. Класс Canvas включает метод create_text для отображения строки, которой можно управлять точно так же, как и любым другим элементом полотна.

При этом есть возможность использовать те же параметры форматирования, что позволит задавать стиль текста: цвет, размер и семейство шрифтов.

В этом примере объединим виджет Entry с содержимым текстового элемента полотна. И если у первого будет стандартный стиль, то текст на полотне можно будет стилизовать:

Вывод текста на полотне

Текстовый элемент по умолчанию будет отображаться с помощью canvas.create_text() и дополнительными параметрами, которые позволят добавить семейство шрифтов Consolas и синий цвет.

Динамическое поведение текстового элемента реализовано с помощью StringVar. Отслеживая эту переменную Tkinter, можно менять содержимое элемента:


import tkinter as tk class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Текстовые элементы Canvas")
self.geometry("300x100")

self.var = tk.StringVar()
self.entry = tk.Entry(self, textvariable=self.var)
self.canvas = tk.Canvas(self, bg="white")

self.entry.pack(pady=5)
self.canvas.pack()
self.update()

w, h = self.canvas.winfo_width(), self.canvas.winfo_height()
options = {"font": "courier", "fill": "blue",
"activefill": "red"}
self.text_id = self.canvas.create_text((w / 2, h / 2), **options)
self.var.trace("w", self.write_text)

def write_text(self, *args):
self.canvas.itemconfig(self.text_id, text=self.var.get()) if __name__ == "__main__":
app = App()
app.mainloop()

Можно ознакомиться с этой программой, введя любой текст в поле ввода, что автоматически обновит его на полотне.

Как работает вывод текста на полотно

В первую очередь создается экземпляр Entry с переменной StringVar и виджетом Canvas:


self.var = tk.StringVar()
self.entry = tk.Entry(self, textvariable=self.var)
self.canvas = tk.Canvas(self, bg="white")

После этого виджеты размещаются с помощью вызовов методов geometry manager Pack. Важно отметить, что update() нужно вызывать в корневом окне, благодаря чему Tkinter будет вынужден обрабатывать все изменения, в данном случае — рендеринг виджетов до того, как метод __init__ продолжит выполнение:


self.entry.pack(pady=5)
self.canvas.pack()
self.update()

Это делается, потому что на следующем шаге будут выполняться вычисления размеров полотна, и до тех пор пока geometry manager не разместит виджет, у него не будет реальных значений высоты и ширины.

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

Эти координаты будут определять положение элемента, и вместе с параметрами стиля их нужно передать в метод create_text(). Аргумент-ключевое слово text — это стандартный параметр, но его можно пропустить, потому что он будет задаваться динамически при изменении значения StringVar:


w, h = self.canvas.winfo_width(), self.canvas.winfo_height()
options = { "font": "courier", "fill": "blue",
"activefill": "red" }
self.text_id = self.canvas.create_text((w/2, h/2), **options)
self.var.trace("w", self.write_text)

Идентификатор, который возвращает create_text(), будет сохранен в поле text_id. Он будет использоваться в методе write_text() для ссылки на элемент. А этот метод будет вызван за счет механизма отслеживания операции записи в экземпляре var.

Для обновления параметра text в обработчике write_text() вызывается метод canvas.itemconfig() с идентификатором элемента в качестве первого аргумента и настройки — как второго.

В этой программе используем поле field_id, сохраненное при создании экземпляра App, а также содержимое StringVar с помощью метода get():

Метод write_text() определен таким образом, что он может получать переменное число аргументов, хотя они не нужны, потому что метод trace() переменных Tkinter передает их в функции обратного вызова.

В методе canvas.create_text() есть много других параметров для изменения внешнего вида элементов полотна.

Размещение текста в левом верхнем углу

Параметр anchor позволяет контролировать положение элемента относительно координат, переданных в качестве первого аргумента в canvas.create_text(). По умолчанию это значение равно tk.CENTER, что значит, что текст будет отцентрирован в этих координатах.

Если же его нужно разместить в верхнем левом углу, то достаточно передать (0, 0) и задать значение tk.NW для anchor, что выровняет его в северо-западном положении прямоугольной области, в которой находится текст:


# ...
options = { "font": "courier", "fill": "blue",
"activefill": "red", "anchor": tk.NW }
self.text_id = self.canvas.create_text((0, 0), **options)

Этот код обеспечит такой результат:

Canvas, рисование графики ч.1 / tkinter 18

Перенос строк

По умолчанию содержимое текстового элемента будет выводиться в одну строку. Параметр width же позволяет задать максимальную ширину строки. В результате если она окажется больше, то содержимое перенесется на новую строку:


# ...
options = { "font": "courier", "fill": "blue",
"activefill": "red", "width": 70 }
self.text_id = self.canvas.create_text((w/2, h/2), **options)

Теперь если написать Hello World, часть текста выйдет за пределы заданной ширины и перенесется на новую строку:

Canvas, рисование графики ч.1 / tkinter 18

Виджет Canvas() — Холст используется для добавления структурированной графики в приложение.

Синтаксис создания виджета подобен, другим объектам tkinter:

widget_name = Canvas(parent, options)

1

  • parent — окно или фрейм (рамка), в котором будет размещаться холст;
  • options — параметры настройки холста.

Базовые параметры

  1. bd — представляет ширину границы. Ширина по умолчанию — 2.
  2. bg — он представляет собой цвет фона холста.
  3. confine — он настроен на то, чтобы холст нельзя было прокручивать за пределами области прокрутки.
  4. cursor — курсор используется как стрелка, круг, точка и т.д. На холсте.
  5. height — представляет размер холста в вертикальном направлении.
  6. highlightcolor — представляет цвет выделения, когда виджет находится в фокусе.
  7. relief — представляет собой тип бордюра. Возможные значения: SUNKEN, RAISED, GROOVE и RIDGE.
  8. scrollregion — представляет координаты, заданные как кортеж, содержащий область холста.
  9. width Он представляет собой ширину холста.
  10. xscrollincrement — если задано положительное значение. Холст размещается только с кратным этому значению.
  11. xscrollcommand — если холст можно прокручивать, этот атрибут должен быть методом .set() горизонтальной полосы прокрутки.
  12. yscrollincrement — работает как xscrollincrement, но управляет вертикальным перемещением.
  13. yscrollcommand — если холст можно прокручивать, этот атрибут должен быть методом .set() вертикальной полосы прокрутки.

В tkinter от класса Canvas() создаются объекты-холсты, на которых можно «рисовать», размещая различные фигуры и объекты. Делается это с помощью вызовов соответствующих методов.

При создании экземпляра Canvas необходимо указать его ширину и высоту. При размещении геометрических примитивов и других объектов указываются их координаты на холсте. Точкой отсчета является верхний левый угол.

canvas_01

В программе ниже создается холст. На нем с помощью метода create_line() рисуются отрезки. Сначала указываются координаты начала (x1, y1), затем – конца (x2, y2):

from tkinter import *

root = Tk()

c = Canvas(root, width=200, height=200, bg='white')
c.pack()

c.create_line(10, 10, 190, 50)
c.create_line(100, 180, 100, 60,
     fill='green', width=5, arrow=LAST,
     dash=(10,2), activefill='lightgreen',
     arrowshape="10 20 10")

root.mainloop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14

canvas_02

Остальные свойства являются необязательными. Так activefill определяет цвет отрезка при наведении на него курсора мыши.

Создание прямоугольников методом create_rectangle():

…
c.create_rectangle(10, 10, 190, 60)
c.create_rectangle(60, 80, 140, 190, fill='yellow', outline='green', width=3, activedash=(5, 4))

1
2
3
4

canvas_03

Первые координаты – верхний левый угол, вторые – правый нижний. В приведенном примере, когда на второй прямоугольник попадает курсор мыши, его рамка становится пунктирной, что определяется свойством activedash.

Методом create_polygon() рисуется произвольный многоугольник путем задания координат каждой его точки:

…
c.create_polygon(100, 10, 20, 90, 180, 90)
c.create_polygon(40, 110, 160, 110, 190, 180, 10, 180, fill='orange', outline='black')

1
2
3
4

canvas_04

Для удобства координаты точек можно заключать в скобки:

…
c.create_polygon((40, 110), (160, 110), (190, 180), (10, 180), fill='orange', outline='black')

1
2
3

Метод create_oval() создает эллипсы. При этом задаются координаты гипотетического прямоугольника, описывающего эллипс. Если нужно получить круг, то соответственно описываемый прямоугольник должен быть квадратом:

…
c.create_oval(50, 10, 150, 110, width=2)
c.create_oval(10, 120, 190, 190, fill='grey70', outline='white')

1
2
3
4

canvas_05

Более сложные для понимания фигуры получаются при использовании метода create_arc(). В зависимости от значения опции style можно получить сектор (по умолчанию), сегмент (CHORD) или дугу (ARC). Также как в случае create_oval() координаты задают прямоугольник, в который вписана окружность (или эллипс), из которой «вырезают» сектор, сегмент или дугу. Опции start присваивается градус начала фигуры, extent определяет угол поворота:

…
c.create_oval(10, 10, 190, 190, fill='lightgrey', outline='white')
c.create_arc(10, 10, 190, 190, start=0, extent=45, fill='red')
c.create_arc(10, 10, 190, 190, start=180, extent=25, fill='orange')
c.create_arc(10, 10, 190, 190, start=240, extent=100, style=CHORD, fill='green')
c.create_arc(10, 10, 190, 190, start=160, extent=-70, style=ARC, outline='darkblue', width=5)

1
2
3
4
5
6
7

canvas_06

В данном примере светло-серый круг используется исключительно для наглядности.

На холсте можно разместить текст. Делается это с помощью метода create_text():

…
c.create_text(100, 100, text="Hello World,nPythonnand Tk", justify=CENTER, font="Verdana 14")
c.create_text(200, 200, text="About this", anchor=SE, fill="grey")

1
2
3
4

canvas_07

По умолчанию в заданной координате располагается центр текстовой надписи. Чтобы изменить это и, например, разместить по указанной координате левую границу текста, используется якорь со значением W (от англ. west – запад). Другие значения: N, NE, E, SE, S, SW, W, NW. Если букв, задающих сторону привязки, две, то вторая определяет вертикальную привязку (вверх или вниз «уйдет» текст от заданной координаты). Свойство justify определяет лишь выравнивание текста относительно себя самого.

Упражнения

  1. Создайте на холсте подобное изображение:

canvas_08

  1. Для создания травы используется цикл.

Canvas. Идентификаторы, теги и анимация

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

В tkinter существует два способа «пометить» фигуры, размещенные на холсте, – это идентификаторы и теги. Первые всегда уникальны для каждого объекта. Два объекта не могут иметь одни и тот же идентификатор. Теги не уникальны. Группа объектов на холсте может иметь один и тот же тег. Это дает возможность менять свойства всей группы. Отдельно взятая фигура на Canvas может иметь как идентификатор, так и тег.

Методы, создающие фигуры на холсте, возвращают численные идентификаторы этих объектов, которые можно присвоить переменным, через которые позднее обращаться к созданным фигурам:

from tkinter import *
root = Tk()
c = Canvas(width=300, height=300, bg='white')
c.focus_set()
c.pack()

ball = c.create_oval(140, 140, 160, 160, fill='green')
c.bind('<Up>', lambda event: c.move(ball, 0, -2))
c.bind('<Down>', lambda event: c.move(ball, 0, 2))
c.bind('<Left>', lambda event: c.move(ball, -2, 0))
c.bind('<Right>', lambda event: c.move(ball, 2, 0))

root.mainloop()

1
2
3
4
5
6
7
8
9
10
11
12
13

В данном примере круг двигается по холсту с помощью стрелок на клавиатуре. Когда создавался круг, его идентификатор был присвоен переменной ball. Метод move() объекта Canvas принимает идентификатор и смещение по осям.

С помощью метода itemconfig() можно изменять другие свойства. Метод coords() устанавливает новые координаты фигуры, если они заданы. Если указывается только идентификатор или тег, то coords() возвращает текущие координаты:

from tkinter import *
root = Tk()
c = Canvas(width=200, height=200, bg='white')
c.pack()

rect = c.create_rectangle(80, 80, 120, 120, fill='lightgreen')

def inFocus(event):
    c.itemconfig(rect, fill='green', width=2)
    c.coords(rect, 70, 70, 130, 130)
c.bind('<FocusIn>', inFocus)

root.mainloop()

1
2
3
4
5
6
7
8
9
10
11
12
13

Здесь при получении холстом фокуса (нажать Tab) изменится цвет и размер квадрата.

В отличие от идентификаторов, которые являются уникальными для каждого объекта, один и тот же тег может присваиваться разным объектам. Дальнейшее обращение к такому тегу позволит изменить все объекты, в которых он был указан. В примере ниже эллипс и линия содержат один и тот же тег, а функция color изменяет цвет всех объектов с тегом group1. Обратите внимание, что в отличие от имени идентификатора (переменная), имя тега заключается в кавычки (строковое значение):

…
oval = c.create_oval(30, 10, 130, 80, tag="group1")
c.create_line(10, 100, 450, 100, tag="group1")

def color(event):
     c.itemconfig('group1',fill="red",width=3)

c.bind('<Button-3>', color)

1
2
3
4
5
6
7
8
9

Метод tag_bind() позволяет привязать событие (например, щелчок кнопкой мыши) к определенной фигуре на Canvas. Таким образом, можно реализовать обращение к различным областям холста с помощью одного и того же события. Пример ниже иллюстрирует, как изменения на холсте зависят от того, где произведен клик:

from tkinter import *

c = Canvas(width=460, height=100, bg='grey80')
c.pack()

oval = c.create_oval(30, 10, 130, 80, fill="orange")
c.create_rectangle(180, 10, 280, 80, tag="rect", fill="lightgreen")
trian = c.create_polygon(330, 80, 380, 10, 430, 80, fill='white',outline="black")

def oval_func(event):
     c.delete(oval)
     c.create_text(80, 50, text="Круг")

def rect_func(event):
     c.delete("rect")
     c.create_text(230, 50, text="Прямоугольник")

def triangle(event):
     c.delete(trian)
     c.create_text(380, 50, text="Треугольник")

c.tag_bind(oval, '<Button-1>', oval_func)
c.tag_bind("rect", '<Button-1>', rect_func)
c.tag_bind(trian, '<Button-1>', triangle)

mainloop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

До кликов:

canvas_11

После кликов:

canvas_12

Метод delete() удаляет объект. Если нужно очистить холст, то вместо идентификаторов или тегов используется константа ALL.

Упражнения

Практическая работа. Анимация в tkinter.

В данной программе создается анимация круга, который движется от левой границы холста до правой:

from tkinter import *

root = Tk()
c = Canvas(root, width=300, height=200, bg="white")
c.pack()

ball = c.create_oval(0, 100, 40, 140, fill='green')

def motion():
    c.move(ball, 1, 0)
    if c.coords(ball)[2] < 300:
        root.after(20, motion)

motion()

root.mainloop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Выражение c.coords(ball) возвращает список текущих координат объекта (в данном случае это ball). Третий элемент списка соответствует его второй координате x.

Метод after() вызывает функцию, переданную вторым аргументом, через количество миллисекунд, указанных первым аргументом.

Изучите приведенную программу и самостоятельно запрограммируйте постепенное движение фигуры в ту точку холста, где пользователь кликает левой кнопкой мыши. Координаты события хранятся в его атрибутах x и y (event.x, event.y).

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить цвет лед ленты
  • Как изменить цвет латуни
  • Как изменить цвет латекса
  • Как изменить цвет ластика фотошоп
  • Как изменить цвет лампы накаливания

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии