На этом шаге мы рассмотрим класс, позволяющий сгруппировать объекты.
Объединить несколько объектов в группу позволяет класс 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. Результат работы приложения
На следующем шаге мы рассмотрим эффекты.