Painter Example¶
Simple painter application based on Qt Widgets.
from PySide6.QtWidgets import (
QWidget,
QMainWindow,
QApplication,
QFileDialog,
QStyle,
QColorDialog,
)
from PySide6.QtCore import QPoint, Qt, QDir, 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
"""
painter = QPainter()
painter.begin(self)
painter.drawPixmap(0, 0, self.pixmap)
painter.end()
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), "Save", self.on_save
)
self._save_action.setShortcut(QKeySequence.Save)
self._open_action = self.bar.addAction(
qApp.style().standardIcon(QStyle.SP_DialogOpenButton), "Open", self.on_open
)
self._open_action.setShortcut(QKeySequence.Open)
self.bar.addAction(
qApp.style().standardIcon(QStyle.SP_DialogResetButton),
"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.set_color(Qt.black)
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(Qt.black, self)
if color:
self.set_color(color)
def set_color(self, color: QColor = Qt.black):
# Create color icon
pix_icon = QPixmap(32, 32)
pix_icon.fill(color)
self.color_action.setIcon(QIcon(pix_icon))
self.painter_widget.pen.setColor(color)
self.color_action.setText(QColor(color).name())
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec())
© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.