为了账号安全,请及时绑定邮箱和手机立即绑定

如何显示我在 PyQt5 中使用 QPainter 绘制的线条的预览

如何显示我在 PyQt5 中使用 QPainter 绘制的线条的预览

子衿沉夜 2023-10-31 19:19:53
我的代码是使用 mousePressEvent 和 mouseReleaseEvent 在 QImage 上绘制线条。它工作正常,但我希望在绘制所述线时(即在 MouseMoveEvent 上)出现一条动态预览线。现在,当我释放鼠标左键时,这条线就会出现,但我看不到我正在绘制的内容。我希望在移动鼠标时显示并更新线条的预览,并且仅在释放鼠标左键时“固定”。与 MS Paint Line 工具完全相同:https://youtu.be/YIw9ybdoM6o ?t=207这是我的代码(它源自 Scribble 示例):from PyQt5.QtCore import QPoint, QRect, QSize, Qtfrom PyQt5.QtGui import QImage, QPainter, QPen, QColor, qRgbfrom PyQt5.QtWidgets import QApplication, QWidget, QMainWindowimport sysclass DrawingArea(QWidget):    def __init__(self, parent=None):        super(DrawingArea, self).__init__(parent)        self.setAttribute(Qt.WA_StaticContents)        self.scribbling = False        self.myPenWidth = 1        self.myPenColor = QColor('#000000')         self.image = QImage()        self.startPoint = QPoint()    def mousePressEvent(self, event):        if event.button() == Qt.LeftButton:            self.startPoint = event.pos()            self.scribbling = True    def mouseReleaseEvent(self, event):        if event.button() == Qt.LeftButton and self.scribbling:            self.drawLineTo(event.pos())            self.scribbling = False    def paintEvent(self, event):        painter = QPainter(self)        dirtyRect = event.rect()        painter.drawImage(dirtyRect, self.image, dirtyRect)    def resizeEvent(self, event):        if self.width() > self.image.width() or self.height() > self.image.height():            newWidth = max(self.width() + 128, self.image.width())            newHeight = max(self.height() + 128, self.image.height())            self.resizeImage(self.image, QSize(newWidth, newHeight))            self.update()        super(DrawingArea, self).resizeEvent(event)我不知道如何显示我正在绘制的线条的预览,而且我还没有找到合适的答案。我该怎么做呢?
查看完整描述

2 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

您可以在方法内绘制线条,paintEvent()而不是直接在图像上绘制,然后在实际释放鼠标时在图像上绘制。


class DrawingArea(QWidget):

    def __init__(self, parent=None):

        super(DrawingArea, self).__init__(parent)


        self.setAttribute(Qt.WA_StaticContents)

        self.scribbling = False

        self.myPenWidth = 1

        self.myPenColor = QColor('#000000') 

        self.image = QImage()

        self.startPoint = self.endPoint = None


    def mousePressEvent(self, event):

        if event.button() == Qt.LeftButton:

            self.startPoint = event.pos()


    def mouseMoveEvent(self, event):

        if self.startPoint:

            self.endPoint = event.pos()

            self.update()


    def mouseReleaseEvent(self, event):

        if self.startPoint and self.endPoint:

            self.updateImage()


    def paintEvent(self, event):

        painter = QPainter(self)

        dirtyRect = event.rect()

        painter.drawImage(dirtyRect, self.image, dirtyRect)

        if self.startPoint and self.endPoint:

            painter.drawLine(self.startPoint, self.endPoint)


    def updateImage(self):

        if self.startPoint and self.endPoint:

            painter = QPainter(self.image)

            painter.setPen(QPen(self.myPenColor, self.myPenWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

            painter.drawLine(self.startPoint, self.endPoint)

            painter.end()

            self.startPoint = self.endPoint = None

            self.update()

请注意,您不需要update()在调整大小事件中调用,因为它是自动调用的。


我还删除了不必要的更新矩形调用,因为在这种情况下它几乎没有用:指定一个应该发生更新的矩形通常是在绘制非常复杂的小部件时完成的(特别是当执行大量计算以正确绘制所有内容并且仅绘制一个小部件的一小部分实际上需要更新)。在您的情况下,计算实际更新矩形几乎比绘制小部件的所有内容更耗时。


查看完整回答
反对 回复 2023-10-31
?
米脂

TA贡献1836条经验 获得超3个赞

例如,它展示了如何实现一个自定义类,它实际上为您提供了一个“绘图板”:

class Canvas(QLabel):


    def __init__(self):

        super().__init__()

        pixmap = QtGui.QPixmap(600, 300)

        self.setPixmap(pixmap)


        self.last_x, self.last_y = None, None

        self.pen_color = QtGui.QColor('#000000')


    def set_pen_color(self, c):

        self.pen_color = QtGui.QColor(c)


    def mouseMoveEvent(self, e):

        if self.last_x is None:  # First event.

            self.last_x = e.x()

            self.last_y = e.y()

            return  # Ignore the first time.


        painter = QtGui.QPainter(self.pixmap())

        p = painter.pen()

        p.setWidth(1)

        p.setColor(self.pen_color)

        painter.setPen(p)

        painter.drawLine(self.last_x, self.last_y, e.x(), e.y())

        painter.end()

        self.update()


        # Update the origin for next time.

        self.last_x = e.x()

        self.last_y = e.y()


    def mouseReleaseEvent(self, e):

        self.last_x = None

        self.last_y = None

您可以在任何需要的地方使用这个 Canvas 类(或者您给它起的任何名称)。例如在主窗口中:


class MainWindow(QMainWindow):

    def __init__(self, parent=None):

        QMainWindow.__init__(self, parent)

        self.canvas = Canvas()

        self.canvas.set_pen_color('#fffee5')  # set the colour you want


        self.setCentralWidget(self.canvas)

        self.show()

希望这能有所帮助!快乐编码!:)


查看完整回答
反对 回复 2023-10-31
  • 2 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信