在 QWidget python GUI 上画一个圆圈

Posted

技术标签:

【中文标题】在 QWidget python GUI 上画一个圆圈【英文标题】:Drawing a circle on a QWidget python GUI 【发布时间】:2020-04-04 20:48:47 【问题描述】:

我正在尝试画一个圆圈而不是点 这是在小部件的任何位置按下事件时绘制红点的类 我想画一个圆(空心圆)作为轮廓,而不是一个隐藏部分图片的实心圆

     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_())

【问题讨论】:

我想第二类定义是非自愿粘贴,对吧?也就是说,我不确定我是否理解您的代码:除了 drawImage 函数之外,我看不到任何绘画。 我只是注释了它绘制的行,这是一个子文件,我将它导入到具有 GUI 和其他功能的主文件中,我对其进行了编辑并添加了加载图像的功能 我仍然看到一个带有缩进的重复类。请按照formatting code 的指南查看您的示例,并在提交编辑之前检查预览,否则我们将难以理解。 你来了,我只是放了课程并附上了我正在处理的链接 我没看到你想画一个圆圈,那在哪里?您是否阅读过有关QPainter 的文档?另外,您的缩进是错误的;正如我已经建议的那样,请在提交任何编辑之前检查预览。我们必须能够按原样复制、粘贴并尝试运行您的代码。 【参考方案1】:

我相信这就是你想要做的。

在这种情况下,您需要利用哪个绘图设备传递给 QPainter。在mousePressEventmouseMoveEvent 期间使用QPainter(self),所以任何绘制的内容只会持续到下一次更新。然后在mouseReleaseEvent对圆的大小满意后,可以用QPainter(self.image)在QImage上画图永久画圆。

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_())

【讨论】:

是的,完全完美,你能告诉我重置它或删除圆圈的功能吗? @HassanKhaledBosha 您的意思是您希望能够撤消最后一个圆圈并重置图像吗?顺便说一句,当答案适当地回答了您的问题时,通常会批准答案。 我添加了撤消 (CTRL+Z) 和重置 (CTRL+R) 功能。 是的,在 push button_clicked 的函数中使用的函数可以移除圆圈 好的,我使用了热键快捷键,但您可以将按钮点击信号相应地连接到 canvas.undocanvas.reset

以上是关于在 QWidget python GUI 上画一个圆圈的主要内容,如果未能解决你的问题,请参考以下文章

在非 GUI 线程中创建 QWidget

如何在 GUI 线程外设置 QWidget 光标

在Matlab的GUI上画两个axis,如何切换?

PyQt4 - QWidget 另存为图像

python, PyQt5模块实现窗口GUI界面,进度条和按钮功能

python, PyQt5模块实现窗口GUI界面,进度条和按钮功能