I've made a simple paint application which can open and save files, draw on pictures with different brush colors and brush sizes, but i don't know how to properly use QRubberBand, so I'm stuck with a blue square appearing on the screen (at the cursor pos). It doesn't do anything with the things I draw, so I'm quite confused. Thanks in advance.
file "graphic.py", the application
# graphic.py
# Импортирую библиотеки
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import io
# Импортирую класс с дизайном
from graphic_ui import Ui_GRedWindow
class GRedactor(QMainWindow, Ui_GRedWindow):
def __init__(self):
super(GRedactor, self).__init__()
self.setupUi(self)
# Создаю холст
self.image = QImage(QSize(800, 600), QImage.Format_RGB32)
# Меняю при необходимости
self.filePath = QFileDialog.getOpenFileName(self, 'Выберите картинку', '',
'jpg (*.jpg);;jpeg (*.jpeg);;png (*.png);;все файлы (*)')[0]
self.create_new_canvas(self.filePath)
# Заполняю холст белым цветом
# Создаю флаг для рисования, устанавливаю дефолтные размер и цвет кисти
self.drawing = False
self.brushType = 'Кисть'
self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
self.brushSize = 4
self.brushColor = Qt.black
# Создаю переменную QPoint для отслеживания курсора
self.position = QPoint()
# Создаю действия QAction
clearAction = self.action
clearAction.triggered.connect(self.clear)
openAction = self.action_2
openAction.triggered.connect(self.open)
saveAction = self.action_3
saveAction.triggered.connect(self.save)
saveAsAction = self.action_4
saveAsAction.triggered.connect(self.save_as)
brushAction = self.action_5
brushAction.triggered.connect(self.brush)
rubberAction = self.action_6
rubberAction.triggered.connect(self.rubber)
pix4 = self.action4px
pix4.triggered.connect(self.pix4)
pix6 = self.action6px
pix6.triggered.connect(self.pix6)
pix8 = self.action8px
pix8.triggered.connect(self.pix8)
pix10 = self.action10px
pix10.triggered.connect(self.pix10)
pix12 = self.action12px
pix12.triggered.connect(self.pix12)
white = self.action_7
white.triggered.connect(self.white)
gray = self.action_8
gray.triggered.connect(self.gray)
black = self.action_9
black.triggered.connect(self.black)
red = self.action_10
red.triggered.connect(self.red)
orange = self.action_11
orange.triggered.connect(self.orange)
yellow = self.action_12
yellow.triggered.connect(self.yellow)
green = self.action_13
green.triggered.connect(self.green)
blue = self.action_14
blue.triggered.connect(self.blue)
dark_blue = self.action_15
dark_blue.triggered.connect(self.dark_blue)
purple = self.action_16
purple.triggered.connect(self.purple)
your_color = self.action_17
your_color.triggered.connect(self.your_color)
def mousePressEvent(self, event):
# По нажатию мыши начинаю рисовать
if event.button() == Qt.LeftButton:
self.drawing = True
# Сохраняю позицию курсора
self.position = event.pos()
def mouseMoveEvent(self, event):
# Рисую по движению мыши
if (event.buttons() & Qt.LeftButton) & self.drawing:
if self.brushType == 'Кисть':
canvas_qp = QPainter(self.image)
canvas_qp.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
canvas_qp.drawLine(self.position, event.pos())
self.position = event.pos()
self.update()
elif self.brushType == 'Ластик':
self.rubberBand.setGeometry(QRect(event.pos(), QSize(self.brushSize, self.brushSize)))
self.rubberBand.show()
self.position = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
# Больше не рисую
self.drawing = False
self.rubberBand.hide()
def paintEvent(self, event):
# Создаю qp для холста
qp = QPainter(self)
# Рисую "точку"
qp.drawImage(self.rect(), self.image, self.image.rect())
def save(self):
self.image.save(self.filePath)
# Сохранить как
def save_as(self):
self.filePath, _ = QFileDialog.getSaveFileName(self, "Сохранить картинку", "",
"PNG(*.png);;JPEG(*.jpg *.jpeg);;Все файлы(*.*)")
if not self.filePath:
return
self.image.save(self.filePath)
# Очистить / Создать новый холст
def clear(self):
self.image.fill(Qt.white)
self.update()
# Открыть
def open(self):
self.filePath, _ = QFileDialog.getOpenFileName(self, "Открыть картинку", "",
"PNG(*.png);;JPEG(*.jpg *.jpeg);;Все файлы(*.*)")
self.create_new_canvas(self.filePath)
def pix4(self):
self.brushSize = 4
def pix6(self):
self.brushSize = 6
def pix8(self):
self.brushSize = 8
def pix10(self):
self.brushSize = 10
def pix12(self):
self.brushSize = 12
def white(self):
self.brushColor = Qt.white
def gray(self):
self.brushColor = Qt.gray
def black(self):
self.brushColor = Qt.black
def red(self):
self.brushColor = Qt.red
def orange(self):
self.brushColor = QColor(255, 140, 0)
def yellow(self):
self.brushColor = Qt.yellow
def green(self):
self.brushColor = Qt.green
def blue(self):
self.brushColor = QColor(0, 190, 255)
def dark_blue(self):
self.brushColor = Qt.darkBlue
# Фиолетовый цвет
def purple(self):
self.brushColor = Qt.darkMagenta
# Свой цвет
def your_color(self):
self.brushColor = QColorDialog.getColor()
def create_new_canvas(self, filepath):
# Не выбран файл - пустой холст
if filepath == '':
self.image = QImage(800, 600, QImage.Format_RGB32)
self.image.fill(Qt.white)
self.resize(800, 600)
else:
# Cоздаю QImage() файла и увеличиваю его при необходимости
self.image = QImage(filepath)
if self.image.width() < 300 or self.image.height() < 300:
self.image = self.image.scaled(300, 300, Qt.KeepAspectRatio)
self.resize(self.image.width(), self.image.height())
self.update()
def brush(self):
self.brushType = 'Кисть'
def rubber(self):
self.brushType = 'Ластик'
def except_hook(cls, exception, traceback):
sys.__excepthook__(cls, exception, traceback)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = GRedactor()
ex.show()
sys.exit(app.exec())
file "graphic_ui.py", ui of the application
# graphic_ui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_GRedWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
self.menu_3 = QtWidgets.QMenu(self.menubar)
self.menu_3.setObjectName("menu_3")
self.menu_4 = QtWidgets.QMenu(self.menubar)
self.menu_4.setObjectName("menu_4")
self.menu_2 = QtWidgets.QMenu(self.menubar)
self.menu_2.setObjectName("menu_2")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.action = QtWidgets.QAction(MainWindow)
self.action.setObjectName("action")
self.action_2 = QtWidgets.QAction(MainWindow)
self.action_2.setObjectName("action_2")
self.action_3 = QtWidgets.QAction(MainWindow)
self.action_3.setObjectName("action_3")
self.action_4 = QtWidgets.QAction(MainWindow)
self.action_4.setObjectName("action_4")
self.action_5 = QtWidgets.QAction(MainWindow)
self.action_5.setObjectName("action_5")
self.action_6 = QtWidgets.QAction(MainWindow)
self.action_6.setObjectName("action_6")
self.action_7 = QtWidgets.QAction(MainWindow)
self.action_7.setObjectName("action_7")
self.action_8 = QtWidgets.QAction(MainWindow)
self.action_8.setObjectName("action_8")
self.action_9 = QtWidgets.QAction(MainWindow)
self.action_9.setObjectName("action_9")
self.action_10 = QtWidgets.QAction(MainWindow)
self.action_10.setObjectName("action_10")
self.action_11 = QtWidgets.QAction(MainWindow)
self.action_11.setObjectName("action_11")
self.action_12 = QtWidgets.QAction(MainWindow)
self.action_12.setObjectName("action_12")
self.action_13 = QtWidgets.QAction(MainWindow)
self.action_13.setObjectName("action_13")
self.action_14 = QtWidgets.QAction(MainWindow)
self.action_14.setObjectName("action_14")
self.action_15 = QtWidgets.QAction(MainWindow)
self.action_15.setObjectName("action_15")
self.action_16 = QtWidgets.QAction(MainWindow)
self.action_16.setObjectName("action_16")
self.action_17 = QtWidgets.QAction(MainWindow)
self.action_17.setObjectName("action_17")
self.action4px = QtWidgets.QAction(MainWindow)
self.action4px.setObjectName("action4px")
self.action6px = QtWidgets.QAction(MainWindow)
self.action6px.setObjectName("action6px")
self.action8px = QtWidgets.QAction(MainWindow)
self.action8px.setObjectName("action8px")
self.action10px = QtWidgets.QAction(MainWindow)
self.action10px.setObjectName("action10px")
self.action12px = QtWidgets.QAction(MainWindow)
self.action12px.setObjectName("action12px")
self.menu.addAction(self.action)
self.menu.addAction(self.action_2)
self.menu.addAction(self.action_3)
self.menu.addAction(self.action_4)
self.menu_3.addAction(self.action_7)
self.menu_3.addAction(self.action_8)
self.menu_3.addAction(self.action_9)
self.menu_3.addAction(self.action_10)
self.menu_3.addAction(self.action_11)
self.menu_3.addAction(self.action_12)
self.menu_3.addAction(self.action_13)
self.menu_3.addAction(self.action_14)
self.menu_3.addAction(self.action_15)
self.menu_3.addAction(self.action_16)
self.menu_3.addAction(self.action_17)
self.menu_4.addAction(self.action4px)
self.menu_4.addAction(self.action6px)
self.menu_4.addAction(self.action8px)
self.menu_4.addAction(self.action10px)
self.menu_4.addAction(self.action12px)
self.menu_2.addAction(self.action_5)
self.menu_2.addAction(self.action_6)
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.menubar.addAction(self.menu_4.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menu.setTitle(_translate("MainWindow", "Файл"))
self.menu_3.setTitle(_translate("MainWindow", "Цвет"))
self.menu_4.setTitle(_translate("MainWindow", "Размер"))
self.menu_2.setTitle(_translate("MainWindow", "Кисть"))
self.action.setText(_translate("MainWindow", "Создать"))
self.action_2.setText(_translate("MainWindow", "Открыть"))
self.action_3.setText(_translate("MainWindow", "Сохранить"))
self.action_4.setText(_translate("MainWindow", "Сохранить как"))
self.action_5.setText(_translate("MainWindow", "Обычная (круглая)"))
self.action_6.setText(_translate("MainWindow", "Ластик"))
self.action_7.setText(_translate("MainWindow", "Белый"))
self.action_8.setText(_translate("MainWindow", "Серый"))
self.action_9.setText(_translate("MainWindow", "Чёрный"))
self.action_10.setText(_translate("MainWindow", "Красный"))
self.action_11.setText(_translate("MainWindow", "Оранжевый"))
self.action_12.setText(_translate("MainWindow", "Жёлтый"))
self.action_13.setText(_translate("MainWindow", "Зелёный"))
self.action_14.setText(_translate("MainWindow", "Голубой"))
self.action_15.setText(_translate("MainWindow", "Синий"))
self.action_16.setText(_translate("MainWindow", "Фиолетовый"))
self.action_17.setText(_translate("MainWindow", "Выбрать свой"))
self.action4px.setText(_translate("MainWindow", "4px"))
self.action6px.setText(_translate("MainWindow", "6px"))
self.action8px.setText(_translate("MainWindow", "8px"))
self.action10px.setText(_translate("MainWindow", "10px"))
self.action12px.setText(_translate("MainWindow", "12px"))
I hope there are no issues with the language