diff options
Diffstat (limited to 'examples/widgets/painting/painter/painter.py')
-rw-r--r-- | examples/widgets/painting/painter/painter.py | 204 |
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()) |