diff options
Diffstat (limited to 'examples/widgets/graphicsview/diagramscene/diagramscene.py')
-rw-r--r-- | examples/widgets/graphicsview/diagramscene/diagramscene.py | 232 |
1 files changed, 99 insertions, 133 deletions
diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.py b/examples/widgets/graphicsview/diagramscene/diagramscene.py index b068a8253..60e05613c 100644 --- a/examples/widgets/graphicsview/diagramscene/diagramscene.py +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.py @@ -1,62 +1,23 @@ - -############################################################################# -## -## Copyright (C) 2013 Riverbank Computing Limited. -## Copyright (C) 2021 The Qt Company Ltd. -## Contact: http://www.qt.io/licensing/ -## -## This file is part of the Qt for Python examples of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:BSD$ -## You may use this file under the terms of the BSD license as follows: -## -## "Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## * Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in -## the documentation and/or other materials provided with the -## distribution. -## * Neither the name of The Qt Company Ltd nor the names of its -## contributors may be used to endorse or promote products derived -## from this software without specific prior written permission. -## -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -## -## $QT_END_LICENSE$ -## -############################################################################# +# Copyright (C) 2013 Riverbank Computing Limited. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import math import sys from PySide6.QtCore import (QLineF, QPointF, QRect, QRectF, QSize, QSizeF, Qt, - Signal) -from PySide6.QtGui import (QAction, QColor, QFont, QIcon, QIntValidator, + Signal, Slot) +from PySide6.QtGui import (QAction, QBrush, QColor, QFont, QIcon, QIntValidator, QPainter, QPainterPath, QPen, QPixmap, QPolygonF) -from PySide6.QtWidgets import (QApplication, QButtonGroup, QComboBox, - QFontComboBox, QGraphicsAnchorLayout, - QGraphicsItem, QGraphicsLineItem, +from PySide6.QtWidgets import (QAbstractButton, QApplication, QButtonGroup, + QComboBox, QFontComboBox, QGraphicsItem, QGraphicsLineItem, QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsScene, QGraphicsView, QGridLayout, QHBoxLayout, QLabel, QMainWindow, QMenu, QMessageBox, QSizePolicy, QToolBox, QToolButton, QWidget) -import diagramscene_rc +import diagramscene_rc # noqa: F401 class Arrow(QGraphicsLineItem): @@ -69,8 +30,7 @@ class Arrow(QGraphicsLineItem): self._my_end_item = endItem self.setFlag(QGraphicsItem.ItemIsSelectable, True) self._my_color = Qt.black - self.setPen(QPen(self._my_color, 2, Qt.SolidLine, - Qt.RoundCap, Qt.RoundJoin)) + self.setPen(QPen(self._my_color, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) def set_color(self, color): self._my_color = color @@ -202,19 +162,19 @@ class DiagramItem(QGraphicsPolygonItem): self._my_polygon = path.toFillPolygon() elif self.diagram_type == self.Conditional: self._my_polygon = QPolygonF([ - QPointF(-100, 0), QPointF(0, 100), - QPointF(100, 0), QPointF(0, -100), - QPointF(-100, 0)]) + QPointF(-100, 0), QPointF(0, 100), + QPointF(100, 0), QPointF(0, -100), + QPointF(-100, 0)]) elif self.diagram_type == self.Step: self._my_polygon = QPolygonF([ - QPointF(-100, -100), QPointF(100, -100), - QPointF(100, 100), QPointF(-100, 100), - QPointF(-100, -100)]) + QPointF(-100, -100), QPointF(100, -100), + QPointF(100, 100), QPointF(-100, 100), + QPointF(-100, -100)]) else: self._my_polygon = QPolygonF([ - QPointF(-120, -80), QPointF(-70, 80), - QPointF(120, 80), QPointF(70, -80), - QPointF(-120, -80)]) + QPointF(-120, -80), QPointF(-70, 80), + QPointF(120, 80), QPointF(70, -80), + QPointF(-120, -80)]) self.setPolygon(self._my_polygon) self.setFlag(QGraphicsItem.ItemIsMovable, True) @@ -238,10 +198,10 @@ class DiagramItem(QGraphicsPolygonItem): def image(self): pixmap = QPixmap(250, 250) pixmap.fill(Qt.transparent) - painter = QPainter(pixmap) - painter.setPen(QPen(Qt.black, 8)) - painter.translate(125, 125) - painter.drawPolyline(self._my_polygon) + with QPainter(pixmap) as painter: + painter.setPen(QPen(Qt.black, 8)) + painter.translate(125, 125) + painter.drawPolyline(self._my_polygon) return pixmap def contextMenuEvent(self, event): @@ -330,8 +290,7 @@ class DiagramScene(QGraphicsScene): item.setPos(mouseEvent.scenePos()) self.item_inserted.emit(item) elif self._my_mode == self.InsertLine: - self.line = QGraphicsLineItem(QLineF(mouseEvent.scenePos(), - mouseEvent.scenePos())) + self.line = QGraphicsLineItem(QLineF(mouseEvent.scenePos(), mouseEvent.scenePos())) self.line.setPen(QPen(self._my_line_color, 2)) self.addItem(self.line) elif self._my_mode == self.InsertText: @@ -367,10 +326,10 @@ class DiagramScene(QGraphicsScene): self.removeItem(self.line) self.line = None - if (len(start_items) and len(end_items) and - isinstance(start_items[0], DiagramItem) and - isinstance(end_items[0], DiagramItem) and - start_items[0] != end_items[0]): + if (len(start_items) and len(end_items) + and isinstance(start_items[0], DiagramItem) + and isinstance(end_items[0], DiagramItem) + and start_items[0] != end_items[0]): start_item = start_items[0] end_item = end_items[0] arrow = Arrow(start_item, end_item) @@ -420,6 +379,7 @@ class MainWindow(QMainWindow): self.setCentralWidget(self.widget) self.setWindowTitle("Diagramscene") + @Slot(QAbstractButton) def background_button_group_clicked(self, button): buttons = self._background_button_group.buttons() for myButton in buttons: @@ -439,6 +399,7 @@ class MainWindow(QMainWindow): self.scene.update() self.view.update() + @Slot(int) def button_group_clicked(self, idx): buttons = self._button_group.buttons() for button in buttons: @@ -451,15 +412,18 @@ class MainWindow(QMainWindow): self.scene.set_item_type(idx) self.scene.set_mode(DiagramScene.InsertItem) + @Slot() def delete_item(self): for item in self.scene.selectedItems(): if isinstance(item, DiagramItem): item.remove_arrows() self.scene.removeItem(item) + @Slot(int) def pointer_group_clicked(self, i): self.scene.set_mode(self._pointer_type_group.checkedId()) + @Slot() def bring_to_front(self): if not self.scene.selectedItems(): return @@ -473,6 +437,7 @@ class MainWindow(QMainWindow): z_value = item.zValue() + 0.1 selected_item.setZValue(z_value) + @Slot() def send_to_back(self): if not self.scene.selectedItems(): return @@ -486,21 +451,26 @@ class MainWindow(QMainWindow): z_value = item.zValue() - 0.1 selected_item.setZValue(z_value) + @Slot(QGraphicsPolygonItem) def item_inserted(self, item): self._pointer_type_group.button(DiagramScene.MoveItem).setChecked(True) self.scene.set_mode(self._pointer_type_group.checkedId()) self._button_group.button(item.diagram_type).setChecked(False) + @Slot(QGraphicsTextItem) def text_inserted(self, item): self._button_group.button(self.insert_text_button).setChecked(False) self.scene.set_mode(self._pointer_type_group.checkedId()) + @Slot(QFont) def current_font_changed(self, font): self.handle_font_change() + @Slot(int) def font_size_changed(self, font): self.handle_font_change() + @Slot(str) def scene_scale_changed(self, scale): new_scale = int(scale[:-1]) / 100.0 old_matrix = self.view.transform() @@ -508,36 +478,40 @@ class MainWindow(QMainWindow): self.view.translate(old_matrix.dx(), old_matrix.dy()) self.view.scale(new_scale, new_scale) + @Slot() def text_color_changed(self): self._text_action = self.sender() self._font_color_tool_button.setIcon(self.create_color_tool_button_icon( - ':/images/textpointer.png', - QColor(self._text_action.data()))) + ':/images/textpointer.png', QColor(self._text_action.data()))) self.text_button_triggered() + @Slot() def item_color_changed(self): self._fill_action = self.sender() self._fill_color_tool_button.setIcon(self.create_color_tool_button_icon( - ':/images/floodfill.png', - QColor(self._fill_action.data()))) + ':/images/floodfill.png', QColor(self._fill_action.data()))) self.fill_button_triggered() + @Slot() def line_color_changed(self): self._line_action = self.sender() self._line_color_tool_button.setIcon(self.create_color_tool_button_icon( - ':/images/linecolor.png', - QColor(self._line_action.data()))) + ':/images/linecolor.png', QColor(self._line_action.data()))) self.line_button_triggered() + @Slot() def text_button_triggered(self): self.scene.set_text_color(QColor(self._text_action.data())) + @Slot() def fill_button_triggered(self): self.scene.set_item_color(QColor(self._fill_action.data())) + @Slot() def line_button_triggered(self): self.scene.set_line_color(QColor(self._line_action.data())) + @Slot() def handle_font_change(self): font = self._font_combo.currentFont() font.setPointSize(int(self._font_size_combo.currentText())) @@ -550,18 +524,19 @@ class MainWindow(QMainWindow): self.scene.set_font(font) + @Slot(QGraphicsItem) def item_selected(self, item): font = item.font() - color = item.defaultTextColor() self._font_combo.setCurrentFont(font) self._font_size_combo.setEditText(str(font.pointSize())) self._bold_action.setChecked(font.weight() == QFont.Bold) self._italic_action.setChecked(font.italic()) self._underline_action.setChecked(font.underline()) + @Slot() def about(self): QMessageBox.about(self, "About Diagram Scene", - "The <b>Diagram Scene</b> example shows use of the graphics framework.") + "The <b>Diagram Scene</b> example shows use of the graphics framework.") def create_tool_box(self): self._button_group = QButtonGroup() @@ -569,12 +544,9 @@ class MainWindow(QMainWindow): self._button_group.idClicked.connect(self.button_group_clicked) layout = QGridLayout() - layout.addWidget(self.create_cell_widget("Conditional", DiagramItem.Conditional), - 0, 0) - layout.addWidget(self.create_cell_widget("Process", DiagramItem.Step), 0, - 1) - layout.addWidget(self.create_cell_widget("Input/Output", DiagramItem.Io), - 1, 0) + layout.addWidget(self.create_cell_widget("Conditional", DiagramItem.Conditional), 0, 0) + layout.addWidget(self.create_cell_widget("Process", DiagramItem.Step), 0, 1) + layout.addWidget(self.create_cell_widget("Input/Output", DiagramItem.Io), 1, 0) text_button = QToolButton() text_button.setCheckable(True) @@ -600,14 +572,14 @@ class MainWindow(QMainWindow): self._background_button_group.buttonClicked.connect(self.background_button_group_clicked) background_layout = QGridLayout() - background_layout.addWidget(self.create_background_cell_widget("Blue Grid", - ':/images/background1.png'), 0, 0) - background_layout.addWidget(self.create_background_cell_widget("White Grid", - ':/images/background2.png'), 0, 1) - background_layout.addWidget(self.create_background_cell_widget("Gray Grid", - ':/images/background3.png'), 1, 0) - background_layout.addWidget(self.create_background_cell_widget("No Grid", - ':/images/background4.png'), 1, 1) + background_layout.addWidget( + self.create_background_cell_widget("Blue Grid", ':/images/background1.png'), 0, 0) + background_layout.addWidget( + self.create_background_cell_widget("White Grid", ':/images/background2.png'), 0, 1) + background_layout.addWidget( + self.create_background_cell_widget("Gray Grid", ':/images/background3.png'), 1, 0) + background_layout.addWidget( + self.create_background_cell_widget("No Grid", ':/images/background4.png'), 1, 1) background_layout.setRowStretch(2, 10) background_layout.setColumnStretch(2, 10) @@ -623,38 +595,37 @@ class MainWindow(QMainWindow): def create_actions(self): self._to_front_action = QAction( - QIcon(':/images/bringtofront.png'), "Bring to &Front", - self, shortcut="Ctrl+F", statusTip="Bring item to front", - triggered=self.bring_to_front) + QIcon(':/images/bringtofront.png'), "Bring to &Front", + self, shortcut="Ctrl+F", statusTip="Bring item to front", + triggered=self.bring_to_front) self._send_back_action = QAction( - QIcon(':/images/sendtoback.png'), "Send to &Back", self, - shortcut="Ctrl+B", statusTip="Send item to back", - triggered=self.send_to_back) + QIcon(':/images/sendtoback.png'), "Send to &Back", self, + shortcut="Ctrl+B", statusTip="Send item to back", + triggered=self.send_to_back) self._delete_action = QAction(QIcon(':/images/delete.png'), - "&Delete", self, shortcut="Delete", - statusTip="Delete item from diagram", - triggered=self.delete_item) + "&Delete", self, shortcut="Delete", + statusTip="Delete item from diagram", + triggered=self.delete_item) self._exit_action = QAction("E&xit", self, shortcut="Ctrl+X", - statusTip="Quit Scenediagram example", triggered=self.close) + statusTip="Quit Scenediagram example", triggered=self.close) self._bold_action = QAction(QIcon(':/images/bold.png'), - "Bold", self, checkable=True, shortcut="Ctrl+B", - triggered=self.handle_font_change) + "Bold", self, checkable=True, shortcut="Ctrl+B", + triggered=self.handle_font_change) self._italic_action = QAction(QIcon(':/images/italic.png'), - "Italic", self, checkable=True, shortcut="Ctrl+I", - triggered=self.handle_font_change) + "Italic", self, checkable=True, shortcut="Ctrl+I", + triggered=self.handle_font_change) self._underline_action = QAction( - QIcon(':/images/underline.png'), "Underline", self, - checkable=True, shortcut="Ctrl+U", - triggered=self.handle_font_change) + QIcon(':/images/underline.png'), "Underline", self, + checkable=True, shortcut="Ctrl+U", + triggered=self.handle_font_change) - self._about_action = QAction("A&bout", self, shortcut="Ctrl+B", - triggered=self.about) + self._about_action = QAction("A&bout", self, shortcut="Ctrl+B", triggered=self.about) def create_menus(self): self._file_menu = self.menuBar().addMenu("&File") @@ -689,32 +660,29 @@ class MainWindow(QMainWindow): self._font_color_tool_button = QToolButton() self._font_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self._font_color_tool_button.setMenu( - self.create_color_menu(self.text_color_changed, Qt.black)) + self.create_color_menu(self.text_color_changed, Qt.black)) self._text_action = self._font_color_tool_button.menu().defaultAction() self._font_color_tool_button.setIcon( - self.create_color_tool_button_icon(':/images/textpointer.png', - Qt.black)) + self.create_color_tool_button_icon(':/images/textpointer.png', Qt.black)) self._font_color_tool_button.setAutoFillBackground(True) self._font_color_tool_button.clicked.connect(self.text_button_triggered) self._fill_color_tool_button = QToolButton() self._fill_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self._fill_color_tool_button.setMenu( - self.create_color_menu(self.item_color_changed, Qt.white)) + self.create_color_menu(self.item_color_changed, Qt.white)) self._fill_action = self._fill_color_tool_button.menu().defaultAction() self._fill_color_tool_button.setIcon( - self.create_color_tool_button_icon(':/images/floodfill.png', - Qt.white)) + self.create_color_tool_button_icon(':/images/floodfill.png', Qt.white)) self._fill_color_tool_button.clicked.connect(self.fill_button_triggered) self._line_color_tool_button = QToolButton() self._line_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self._line_color_tool_button.setMenu( - self.create_color_menu(self.line_color_changed, Qt.black)) + self.create_color_menu(self.line_color_changed, Qt.black)) self._line_action = self._line_color_tool_button.menu().defaultAction() self._line_color_tool_button.setIcon( - self.create_color_tool_button_icon(':/images/linecolor.png', - Qt.black)) + self.create_color_tool_button_icon(':/images/linecolor.png', Qt.black)) self._line_color_tool_button.clicked.connect(self.line_button_triggered) self._text_tool_bar = self.addToolBar("Font") @@ -739,8 +707,7 @@ class MainWindow(QMainWindow): self._pointer_type_group = QButtonGroup() self._pointer_type_group.addButton(pointer_button, DiagramScene.MoveItem) - self._pointer_type_group.addButton(line_pointer_button, - DiagramScene.InsertLine) + self._pointer_type_group.addButton(line_pointer_button, DiagramScene.InsertLine) self._pointer_type_group.idClicked.connect(self.pointer_group_clicked) self._scene_scale_combo = QComboBox() @@ -795,8 +762,7 @@ class MainWindow(QMainWindow): color_menu = QMenu(self) for color, name in zip(colors, names): - action = QAction(self.create_color_icon(color), name, self, - triggered=slot) + action = QAction(self.create_color_icon(color), name, self, triggered=slot) action.setData(QColor(color)) color_menu.addAction(action) if color == defaultColor: @@ -806,22 +772,22 @@ class MainWindow(QMainWindow): def create_color_tool_button_icon(self, imageFile, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) - painter = QPainter(pixmap) - image = QPixmap(imageFile) - target = QRect(0, 0, 50, 60) - source = QRect(0, 0, 42, 42) - painter.fillRect(QRect(0, 60, 50, 80), color) - painter.drawPixmap(target, image, source) - painter.end() + + with QPainter(pixmap) as painter: + image = QPixmap(imageFile) + target = QRect(0, 0, 50, 60) + source = QRect(0, 0, 42, 42) + painter.fillRect(QRect(0, 60, 50, 80), color) + painter.drawPixmap(target, image, source) return QIcon(pixmap) def create_color_icon(self, color): pixmap = QPixmap(20, 20) - painter = QPainter(pixmap) - painter.setPen(Qt.NoPen) - painter.fillRect(QRect(0, 0, 20, 20), color) - painter.end() + + with QPainter(pixmap) as painter: + painter.setPen(Qt.NoPen) + painter.fillRect(QRect(0, 0, 20, 20), color) return QIcon(pixmap) |