How to make a rubber band in my PyQt5 paint application?

33 views Asked by At

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

0

There are 0 answers