aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets/painting/painter/painter.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/painting/painter/painter.py')
-rw-r--r--examples/widgets/painting/painter/painter.py204
1 files changed, 204 insertions, 0 deletions
diff --git a/examples/widgets/painting/painter/painter.py b/examples/widgets/painting/painter/painter.py
new file mode 100644
index 000000000..2ca078ad9
--- /dev/null
+++ b/examples/widgets/painting/painter/painter.py
@@ -0,0 +1,204 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtWidgets import (
+ QWidget,
+ QMainWindow,
+ QApplication,
+ QFileDialog,
+ QStyle,
+ QColorDialog,
+)
+from PySide6.QtCore import Qt, Slot, QStandardPaths
+from PySide6.QtGui import (
+ QMouseEvent,
+ QPaintEvent,
+ QPen,
+ QAction,
+ QPainter,
+ QColor,
+ QPixmap,
+ QIcon,
+ QKeySequence,
+)
+import sys
+
+
+class PainterWidget(QWidget):
+ """A widget where user can draw with their mouse
+
+ The user draws on a QPixmap which is itself paint from paintEvent()
+
+ """
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.setFixedSize(680, 480)
+ self.pixmap = QPixmap(self.size())
+ self.pixmap.fill(Qt.white)
+
+ self.previous_pos = None
+ self.painter = QPainter()
+ self.pen = QPen()
+ self.pen.setWidth(10)
+ self.pen.setCapStyle(Qt.RoundCap)
+ self.pen.setJoinStyle(Qt.RoundJoin)
+
+ def paintEvent(self, event: QPaintEvent):
+ """Override method from QWidget
+
+ Paint the Pixmap into the widget
+
+ """
+ with QPainter(self) as painter:
+ painter.drawPixmap(0, 0, self.pixmap)
+
+ def mousePressEvent(self, event: QMouseEvent):
+ """Override from QWidget
+
+ Called when user clicks on the mouse
+
+ """
+ self.previous_pos = event.position().toPoint()
+ QWidget.mousePressEvent(self, event)
+
+ def mouseMoveEvent(self, event: QMouseEvent):
+ """Override method from QWidget
+
+ Called when user moves and clicks on the mouse
+
+ """
+ current_pos = event.position().toPoint()
+ self.painter.begin(self.pixmap)
+ self.painter.setRenderHints(QPainter.Antialiasing, True)
+ self.painter.setPen(self.pen)
+ self.painter.drawLine(self.previous_pos, current_pos)
+ self.painter.end()
+
+ self.previous_pos = current_pos
+ self.update()
+
+ QWidget.mouseMoveEvent(self, event)
+
+ def mouseReleaseEvent(self, event: QMouseEvent):
+ """Override method from QWidget
+
+ Called when user releases the mouse
+
+ """
+ self.previous_pos = None
+ QWidget.mouseReleaseEvent(self, event)
+
+ def save(self, filename: str):
+ """ save pixmap to filename """
+ self.pixmap.save(filename)
+
+ def load(self, filename: str):
+ """ load pixmap from filename """
+ self.pixmap.load(filename)
+ self.pixmap = self.pixmap.scaled(self.size(), Qt.KeepAspectRatio)
+ self.update()
+
+ def clear(self):
+ """ Clear the pixmap """
+ self.pixmap.fill(Qt.white)
+ self.update()
+
+
+class MainWindow(QMainWindow):
+ """An Application example to draw using a pen """
+
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent)
+
+ self.painter_widget = PainterWidget()
+ self.bar = self.addToolBar("Menu")
+ self.bar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
+ self._save_action = self.bar.addAction(
+ qApp.style().standardIcon(QStyle.SP_DialogSaveButton), # noqa: F821
+ "Save", self.on_save
+ )
+ self._save_action.setShortcut(QKeySequence.Save)
+ self._open_action = self.bar.addAction(
+ qApp.style().standardIcon(QStyle.SP_DialogOpenButton), # noqa: F821
+ "Open", self.on_open
+ )
+ self._open_action.setShortcut(QKeySequence.Open)
+ self.bar.addAction(
+ qApp.style().standardIcon(QStyle.SP_DialogResetButton), # noqa: F821
+ "Clear",
+ self.painter_widget.clear,
+ )
+ self.bar.addSeparator()
+
+ self.color_action = QAction(self)
+ self.color_action.triggered.connect(self.on_color_clicked)
+ self.bar.addAction(self.color_action)
+
+ self.setCentralWidget(self.painter_widget)
+
+ self.color = Qt.black
+ self.set_color(self.color)
+
+ self.mime_type_filters = ["image/png", "image/jpeg"]
+
+ @Slot()
+ def on_save(self):
+
+ dialog = QFileDialog(self, "Save File")
+ dialog.setMimeTypeFilters(self.mime_type_filters)
+ dialog.setFileMode(QFileDialog.AnyFile)
+ dialog.setAcceptMode(QFileDialog.AcceptSave)
+ dialog.setDefaultSuffix("png")
+ dialog.setDirectory(
+ QStandardPaths.writableLocation(QStandardPaths.PicturesLocation)
+ )
+
+ if dialog.exec() == QFileDialog.Accepted:
+ if dialog.selectedFiles():
+ self.painter_widget.save(dialog.selectedFiles()[0])
+
+ @Slot()
+ def on_open(self):
+
+ dialog = QFileDialog(self, "Save File")
+ dialog.setMimeTypeFilters(self.mime_type_filters)
+ dialog.setFileMode(QFileDialog.ExistingFile)
+ dialog.setAcceptMode(QFileDialog.AcceptOpen)
+ dialog.setDefaultSuffix("png")
+ dialog.setDirectory(
+ QStandardPaths.writableLocation(QStandardPaths.PicturesLocation)
+ )
+
+ if dialog.exec() == QFileDialog.Accepted:
+ if dialog.selectedFiles():
+ self.painter_widget.load(dialog.selectedFiles()[0])
+
+ @Slot()
+ def on_color_clicked(self):
+
+ color = QColorDialog.getColor(self.color, self)
+
+ if color:
+ self.set_color(color)
+
+ def set_color(self, color: QColor = Qt.black):
+
+ self.color = color
+ # Create color icon
+ pix_icon = QPixmap(32, 32)
+ pix_icon.fill(self.color)
+
+ self.color_action.setIcon(QIcon(pix_icon))
+ self.painter_widget.pen.setColor(self.color)
+ self.color_action.setText(QColor(self.color).name())
+
+
+if __name__ == "__main__":
+
+ app = QApplication(sys.argv)
+
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())