Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Рисование в PyQt5 [Урок №10]

Рисование в PyQt5

Система рисования PyQt5 может использовать в работе векторную графику, изображения и контур основанного на шрифте текста. Рисование необходимо в приложениях, когда мы хотим изменить или увеличить существующий виджет, или мы создаём пользовательский виджет с нуля. Чтобы сделать рисунок, мы используем API рисования, предоставленное инструментарием PyQt5.

Рисование делается в рамках метода paintEvent(). Код рисования размещается между методами begin() и end() объекта QPainter. Он исполняет низкоуровневое рисование на виджетах и других окрашиваемых элементах.

Рисование текста

Мы начинаем с рисования некоторого Unicode-текста в клиентском пространстве окна.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QFont
from PyQt5.QtCore import Qt
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):      
        self.text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Draw text')
        self.show()
        
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        self.drawText(event, qp)
        qp.end()
        
    def drawText(self, event, qp):
        qp.setPen(QColor(168, 34, 3))
        qp.setFont(QFont('Decorative', 10))
        qp.drawText(event.rect(), Qt.AlignCenter, self.text)        
                
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В нашем примере, мы рисуем русскоязычный текст. Текст выровнен вертикально и горизонтально.

def paintEvent(self, event):
...

Рисование делается в пределах события рисования.

qp = QPainter()
qp.begin(self)
self.drawText(event, qp)
qp.end()

Класс QPainter отвечает за все низкоуровневое рисование. Все методы рисования идут между методами begin() и end(). Фактическое рисование делегируется методу drawText().

qp.setPen(QColor(168, 34, 3))
qp.setFont(QFont('Decorative', 10))

Здесь мы определяем карандаш и шрифт, которые используются, чтобы рисовать текст.

qp.drawText(event.rect(), Qt.AlignCenter, self.text)

Метод drawText() рисует текст в окне. Метод rect() события рисования возвращает прямоугольник, которому необходимо быть обновлённым.

Рисование текста

Рисунок: Рисование текста

Рисование точек

Точка – это самый простой графический объект, который может быть нарисован. Это маленькое пятнышко в окне. Для выбора случайного места в окне, мы использовали модуль random python для генерации случайных точек.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys, random
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtCore import Qt
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):      
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Points')
        self.show()
        
    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawPoints(qp)
        qp.end()
        
    def drawPoints(self, qp):
        qp.setPen(Qt.red)
        size = self.size()
        
        for i in range(1000):
            x = random.randint(1, size.width()-1)
            y = random.randint(1, size.height()-1)
            qp.drawPoint(x, y)     
                
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В нашем примере, мы произвольным образом рисуем 1000 красных точек в клиентской части окна.

qp.setPen(Qt.red)

Мы устанавливаем карандаш красного цвета. Мы используем предопределённую цветовую констранту Qt.red.

size = self.size()

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

qp.drawPoint(x, y)

Мы рисуем точку с помощью метода drawPoint().

Точки

Рисунок: Точки

Цвета

Цвет – это объект, представляющий собой комбинацию красного, зелёного и синего (RGB) значений интенсивности. Корректные значения RGB находятся в диапазоне от 0 до 255. Мы можем определить цвет разными способами. Самый распространённый – десятичные значения RGB или шестнадцатеричные значения. Мы также можем использовать значения RGBA, которые обозначают красный, зелёный, синий и альфа-канал. Здесь мы добавляем немного дополнительной информации относительно прозрачности. Значение альфа 255 определяет полную непрозрачность, 0 – полная прозрачность, т.е. цвет невидим.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QBrush
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):      
        self.setGeometry(300, 300, 350, 100)
        self.setWindowTitle('Colours')
        self.show()
 
    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawRectangles(qp)
        qp.end()
        
    def drawRectangles(self, qp):
        col = QColor(0, 0, 0)
        col.setNamedColor('#d4d4d4')
        qp.setPen(col)
        qp.setBrush(QColor(200, 0, 0))
        qp.drawRect(10, 15, 90, 60)
        qp.setBrush(QColor(255, 80, 0, 160))
        qp.drawRect(130, 15, 90, 60)
        qp.setBrush(QColor(25, 0, 90, 200))
        qp.drawRect(250, 15, 90, 60)
              
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В нашем примере, мы рисуем 3 окрашенных прямоугольника.

color = QColor(0, 0, 0)
color.setNamedColor('#d4d4d4')

Здесь мы определяем цвет, используя шестнадцатеричную систему счисления.

qp.setBrush(QColor(200, 0, 0))
qp.drawRect(10, 15, 90, 60)

Здесь мы определяем кисть и рисуем прямоугольник. Кисть – это элементарный графический объект, который используется, чтобы рисовать фон очертания. Метод drawRext() принимает четыре параметра. Первые два – значения x и y на осях. Третий и четвёртый параметры – ширина и высота прямоугольника. Метод рисует прямоугольник, используя текущие карандаш и кисть.

Цвета

Рисунок: Цвета

QPen

QPen – это элементарный графический объект. Он используется, чтобы рисовать линии, кривые и контуры прямоугольников, эллипсов, многоугольников и других форм.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtCore import Qt
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):      
        self.setGeometry(300, 300, 280, 270)
        self.setWindowTitle('Pen styles')
        self.show()
        
    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawLines(qp)
        qp.end()
        
    def drawLines(self, qp):
        pen = QPen(Qt.black, 2, Qt.SolidLine)
 
        qp.setPen(pen)
        qp.drawLine(20, 40, 250, 40)
 
        pen.setStyle(Qt.DashLine)
        qp.setPen(pen)
        qp.drawLine(20, 80, 250, 80)
 
        pen.setStyle(Qt.DashDotLine)
        qp.setPen(pen)
        qp.drawLine(20, 120, 250, 120)
 
        pen.setStyle(Qt.DotLine)
        qp.setPen(pen)
        qp.drawLine(20, 160, 250, 160)
 
        pen.setStyle(Qt.DashDotDotLine)
        qp.setPen(pen)
        qp.drawLine(20, 200, 250, 200)
 
        pen.setStyle(Qt.CustomDashLine)
        pen.setDashPattern([1, 4, 5, 4])
        qp.setPen(pen)
        qp.drawLine(20, 240, 250, 240)
              
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

В нашем примере, мы рисуем шесть линий. Линии рисуются в шести разных стилях карандаша. Существует пять предопределённых стилей карандаша. Мы также можем создать пользовательские стили карандаша. Последняя линия нарисована с использованием пользовательского стиля.

pen = QPen(Qt.black, 2, Qt.SolidLine)

Мы создаём объект QPen. Цвет – чёрный. Ширина устанавливается в 2 пикселя так, чтобы мы могли видеть различия между стилями карандаша. Qt.SolidLine – это один из предопределённых стилей.

pen.setStyle(Qt.CustomDashLine)
pen.setDashPattern([1, 4, 5, 4])
qp.setPen(pen)

Здесь мы определяем пользовательский стиль карандаша. Мы устанавливаем стиль карандаша Qt.CustomDashLine и вызываем метод setDashPattern(). Список чисел определяет стиль. Может быть даже несколько чисел. Нечётные числа определяют штрихи, чётные числа – промежутки. Чем больше число, тем больше промежуток или штрих. Наш образец – штрих в 1 пиксель, промежуток в 4 пикселя, штрих в 5 пикселей, промежуток в 4 пикселя, и т.д.

Стили карандаша

Рисунок: Стили карандаша

QBrush

QBrush – это элементарный графический объект. Он используется для рисования фона графических форм, таких как прямоугольники, эллипсы или многоугольники. Кисть может быть трёх разных типов: предопределённая кисть, градиент, образец текстуры.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QBrush
from PyQt5.QtCore import Qt
 
class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):      
        self.setGeometry(300, 300, 355, 280)
        self.setWindowTitle('Brushes')
        self.show()
        
    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawBrushes(qp)
        qp.end()
        
    def drawBrushes(self, qp):
        brush = QBrush(Qt.SolidPattern)
        qp.setBrush(brush)
        qp.drawRect(10, 15, 90, 60)
 
        brush.setStyle(Qt.Dense1Pattern)
        qp.setBrush(brush)
        qp.drawRect(130, 15, 90, 60)
 
        brush.setStyle(Qt.Dense2Pattern)
        qp.setBrush(brush)
        qp.drawRect(250, 15, 90, 60)
 
        brush.setStyle(Qt.Dense3Pattern)
        qp.setBrush(brush)
        qp.drawRect(10, 105, 90, 60)
 
        brush.setStyle(Qt.DiagCrossPattern)
        qp.setBrush(brush)
        qp.drawRect(10, 105, 90, 60)
 
        brush.setStyle(Qt.Dense5Pattern)
        qp.setBrush(brush)
        qp.drawRect(130, 105, 90, 60)
 
        brush.setStyle(Qt.Dense6Pattern)
        qp.setBrush(brush)
        qp.drawRect(250, 105, 90, 60)
 
        brush.setStyle(Qt.HorPattern)
        qp.setBrush(brush)
        qp.drawRect(10, 195, 90, 60)
 
        brush.setStyle(Qt.VerPattern)
        qp.setBrush(brush)
        qp.drawRect(130, 195, 90, 60)
 
        brush.setStyle(Qt.BDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(250, 195, 90, 60)
              
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

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

brush = QBrush(Qt.SolidPattern)
qp.setBrush(brush)
qp.drawRect(10, 15, 90, 60)

Мы определяем объект кисти. Мы устанавливаем его в объект рисования и рисуем прямоугольник с помощью вызова метода drawRect().

Кисти

Рисунок: Кисти

В этой части руководства PyQt5, мы сделали некоторые основы рисования.

Оставьте комментарий!

Используйте нормальные имена.

Имя и сайт используются только при регистрации

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

(обязательно)