Шаг 227.
Библиотека PyQt5.
Графическая сцена. Группировка объектов

    На этом шаге мы рассмотрим класс, позволяющий сгруппировать объекты.

    Объединить несколько объектов в группу позволяет класс QGraphicsItemGroup. Над сгруппированными объектами можно выполнять различные преобразования - например, перемещать или поворачивать их одновременно. Иерархия наследования для класса QGraphicsItemGroup выглядит так:

  QGraphicsItem - QGraphicsItemGroup

    Формат конструктора класса:

  <Объект> = QGraphicsItemGroup([parent=None])

    В параметре parent можно указать ссылку на родительский объект.

    Класс QGraphicsItemGroup наследует все методы класса QGraphicsItem и поддерживает следующие методы (здесь приведены только основные - полный их список доступен на странице https://doc.qt.io/qt-5/qgraphicsitemgroup.html):

    Создать группу и добавить ее на сцену можно и с помощью метода createItemGroup(<Список с объектами>) класса QGraphicsScene. Метод возвращает ссылку на группу (экземпляр класса QGraphicsItemGroup). Удалить группу со сцены позволяет метод destroyItemGroup(<QGraphicsItemGroup>) класса QGraphicsScene.

    Добавить объект в группу позволяет также метод setGroup(<QGraphicsItemGroup>) класса QGraphicsItem. Получить ссылку на группу, в которой находится объект, можно вызовом метода group() класса QGraphicsItem. Если объект не находится ни в какой группе, метод возвращает None.

    В качетве примера создания и использования группы возьмем приложение из 223 шага и объединим объекты линии и эллипса в одну группу. Чтобы показать наличие созданной группы, будем двигать ее по горизонтали, используя кнопки W (смещение группы на 5 пикселей влево) и Q (смещение группы на 5 пикселей вправо). Кнопка Z будет использоваться для удаления/добавления линии в группу. Тем самым, удалив линию, мы не сможем ее двигать указанными кнопками. После ее повторного добавления в группу она снова будет управляться указанными кнопками.

    Текст приложения.

from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsScene, 
     QGraphicsView, QGraphicsItem, QGraphicsLineItem, QGraphicsEllipseItem, 
     QGraphicsItemGroup
from PyQt5.QtGui import QPen, QBrush
from PyQt5.Qt import Qt
 
import sys
 
class Window(QMainWindow):
    def __init__(self):
        super().__init__()
 
        self.title = "Пример группировки объектов"
        self.top = 200
        self.left = 500
        self.width = 400
        self.height = 300

        self.pos = 0 # Смещение 
        self.YN = True # Присутствует или нет линия в группе
        
        self.setWindowTitle(self.title)
        # Задание местоположения и размера окна
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.scene = QGraphicsScene()
        # Создание инструмента для отрисовки графической сцены
        self.graphicView = QGraphicsView(self.scene, self)
        # Задание местоположения и размера графической сцены
        self.graphicView.setGeometry(0, 0, self.width, self.height)
  
    def plot(self):
        # Задание цветов
        color = Qt.green
        color1 = Qt.red
        color2 = Qt.blue
        # Создание эллипса
        self.ellipse = QGraphicsEllipseItem(50, 50, 200, 200)
        # Определение цвета границы и заполнения
        self.ellipse.setPen(QPen(color1))
        self.ellipse.setBrush(color)
        # Создание линии
        self.line = QGraphicsLineItem(30, 30, 250, 30)
        # Определение ее цвета
        self.line.setPen(QPen(color2))
        # Создание группы
        self.group = QGraphicsItemGroup()
        # Добавление в группу эллипса и линии
        self.group.addToGroup(self.ellipse)
        self.group.addToGroup(self.line)
        # Добавление группы на сцену
        self.scene.addItem(self.group)

    def keyPressEvent(self, event):
        # Обработчик нажатия клавиш
        # Q - смещение группы на 5 пикселей вправо
        # W - смещение группы на 5 пикселей влево
        # Z - удаление/добавлени линии в группу
        if event.key() == QtCore.Qt.Key_Q:   # Q
            self.pos += 5
            self.group.setX(self.pos)
        elif event.key() == QtCore.Qt.Key_W: # W
            self.pos -= 5
            self.group.setX(self.pos)
        elif event.key() == QtCore.Qt.Key_Z: # Z 
            if self.YN == True: # Если линия есть в группе...
                # ... то удаляем ее
                self.group.removeFromGroup(self.line)
                self.YN = False
            else: # Если линии нет в группе...
                # ... то добавляем ее
                self.group.addToGroup(self.line)
                self.YN = True
        event.accept() # Завершение обработки события

 
App = QApplication(sys.argv)
window = Window()
window.show() # Демонстрация окна
window.plot() # Построение и перерисовка окна

sys.exit(App.exec())
Архив с файлом можно взять здесь.

    Результат работы приложения изображен на рисунке 1. Обратите внимание, что сначала двигаются две фигуры, потому что линия является частью группы. После удаления из группы, линия остается на месте, а после повторного включения в группу, снова приходит в движение.


Рис.1. Результат работы приложения

    На следующем шаге мы рассмотрим эффекты.




Предыдущий шаг Содержание Следующий шаг