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

我的代码是使用 mousePressEvent 和 mouseReleaseEvent 在 QImage 上绘制线条。它工作正常,但我希望在绘制所述线时(即在 MouseMoveEvent 上)出现一条动态预览线。现在,当我释放鼠标左键时,这条线就会出现,但我看不到我正在绘制的内容。

我希望在移动鼠标时显示并更新线条的预览,并且仅在释放鼠标左键时“固定”。与 MS Paint Line 工具完全相同:https://youtu.be/YIw9ybdoM6o ?t=207

这是我的代码(它源自 Scribble 示例):

from PyQt5.QtCore import QPoint, QRect, QSize, Qt

from PyQt5.QtGui import QImage, QPainter, QPen, QColor, qRgb

from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow

import sys


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 = 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)



我不知道如何显示我正在绘制的线条的预览,而且我还没有找到合适的答案。我该怎么做呢?


子衿沉夜
浏览 139回答 2
2回答

ibeautiful

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

米脂

例如,它展示了如何实现一个自定义类,它实际上为您提供了一个“绘图板”: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()希望这能有所帮助!快乐编码!:)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python