Рисование круга на QWidget python GUI - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь нарисовать круг вместо точек. Вот класс, где он рисует красные точки при нажатии на событие в любом месте в виджете. Я хочу нарисовать круг (полый круг) как контур, а не solid круг, скрывающий часть моей картины

     import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *

        class Canvas(QWidget):

            def __init__(self, photo, *args, **kwargs):
                super().__init__(*

args, **kwargs)
            self.image = QImage(photo)
            self.setFixedSize(self.image.width(), self.image.height())

        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                qp = QPainter(self.image)
                qp.setRenderHint(QPainter.Antialiasing)
                qp.setPen(QPen(Qt.red, 5))
                qp.setBrush(Qt.red)
                qp.drawPoint(event.pos())
                self.update()

        def paintEvent(self, event):
            qp = QPainter(self)
            rect = event.rect()
            qp.drawImage(rect, self.image, rect)


    class MainWindow(QMainWindow):

        def __init__(self):
            super().__init__()
            w = QWidget()
            self.setCentralWidget(w)
            grid = QGridLayout(w)
            grid.addWidget(Canvas('photo.jpeg'))

    if __name__ == '__main__':
        app = QApplication(sys.argv)
        gui = MainWindow()
        gui.show()
        sys.exit(app.exec_())

Ответы [ 2 ]

2 голосов
/ 05 апреля 2020

Я считаю, что это то, что вы пытаетесь сделать.

enter image description here

В этом случае вам нужно воспользоваться преимуществами устройства для прохождения краски в QPainter. Во время mousePressEvent и mouseReleaseEvent используйте QPainter(self), поэтому все окрашенное будет действовать только до следующего обновления. Затем в mouseReleaseEvent, когда вас устраивает размер круга, вы можете нарисовать QImage с помощью QPainter(self.image), чтобы нарисовать круг постоянно.

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class Canvas(QWidget):

    def __init__(self, photo, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.image = QImage(photo)
        self.setFixedSize(self.image.width(), self.image.height())
        self.pressed = self.moving = False
        self.revisions = []

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pressed = True
            self.center = event.pos()
            self.update()

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.moving = True
            r = (event.pos().x() - self.center.x()) ** 2 + (event.pos().y() - self.center.y()) ** 2
            self.radius = r ** 0.5
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.revisions.append(self.image.copy())
            qp = QPainter(self.image)
            self.draw_circle(qp) if self.moving else self.draw_point(qp)
            self.pressed = self.moving = False
            self.update()

    def paintEvent(self, event):
        qp = QPainter(self)
        rect = event.rect()
        qp.drawImage(rect, self.image, rect)
        if self.moving:
            self.draw_circle(qp)
        elif self.pressed:
            self.draw_point(qp)

    def draw_point(self, qp):
        qp.setPen(QPen(Qt.black, 5))
        qp.drawPoint(self.center)

    def draw_circle(self, qp):
        qp.setRenderHint(QPainter.Antialiasing)
        qp.setPen(QPen(Qt.black, 3, Qt.DashLine))
        qp.drawEllipse(self.center, self.radius, self.radius)

    def undo(self):
        if self.revisions:
            self.image = self.revisions.pop()
            self.update()

    def reset(self):
        if self.revisions:
            self.image = self.revisions[0]
            self.revisions.clear()
            self.update()


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        w = QWidget()
        self.setCentralWidget(w)
        canvas = Canvas('photo.png')
        grid = QGridLayout(w)
        grid.addWidget(canvas)
        QShortcut(QKeySequence('Ctrl+Z'), self, canvas.undo)
        QShortcut(QKeySequence('Ctrl+R'), self, canvas.reset)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    gui = MainWindow()
    gui.show()
    sys.exit(app.exec_())
0 голосов
/ 06 апреля 2020

Вот файл, в котором находится мой класс. Вам нужны более подробные сведения?

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys


class Canvas(QWidget):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.image = None
        self.pressed = self.moving = False
        self.revisions = []

    def set_image(self, qimage):
        qimage = qimage.scaled(self.size(), Qt.KeepAspectRatio)
        self.image = qimage
        self.setFixedSize(self.image.width(), self.image.height())
        # self.setFixedSize(309, 300)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pressed = True
            self.center = event.pos()
            self.update()

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.moving = True
            r = (event.pos().x() - self.center.x()) ** 2 + (event.pos().y() - self.center.y()) ** 2
            self.radius = r ** 0.5
            self.update()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.revisions.append(self.image.copy())
            qp = QPainter(self.image)
            self.draw_circle(qp) if self.moving else self.draw_point(qp)
            self.pressed = self.moving = False
            self.update()

    def paintEvent(self, event):
        if self.image:
            qp = QPainter(self)
            rect = event.rect()
            qp.drawImage(rect, self.image, rect)
            if self.moving:
                self.draw_circle(qp)
            elif self.pressed:
                self.draw_point(qp)

    def draw_point(self, qp):
        qp.setPen(QPen(Qt.black, 5))
        qp.drawPoint(self.center)

    def draw_circle(self, qp):
        qp.setRenderHint(QPainter.Antialiasing)
        qp.setPen(QPen(Qt.black, 3, Qt.DashLine))
        qp.drawEllipse(self.center, self.radius, self.radius)

    def undo(self):
        if self.revisions:
            self.image = self.revisions.pop()
            self.update()

    def reset(self):
        if self.revisions:
            self.image = self.revisions[0]
            self.revisions.clear()
            self.update()

, а вот другой файл моего основного GUI

from canvas import *
class ApplicationWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(ApplicationWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        QShortcut(QKeySequence('Ctrl+Z'), self, Canvas.undo)
        QShortcut(QKeySequence('Ctrl+R'), self, Canvas.reset)
def main():
    app = QtWidgets.QApplication(sys.argv)
    application = ApplicationWindow()
    application.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
...