Python 如何显示行I';在PyQt5中使用QPainter绘制m图纸

Python 如何显示行I';在PyQt5中使用QPainter绘制m图纸,python,pyqt,pyqt5,qpainter,Python,Pyqt,Pyqt5,Qpainter,我的代码是使用MousePresseEvent和mouseReleaseEvent在QImage上绘制线条。它的作品很好,但我想一个动态预览线出现时,我画说的线(即在MouseMoveEvent)。现在,当我松开鼠标左键时,这条线就出现了,我看不到我在画什么 我希望在移动鼠标时显示和更新线条预览,并且在释放鼠标左键时仅“固定”。与MS绘制线工具完全相同: 以下是我的代码(它源自Scribble示例): 我不知道如何显示我正在绘制的线条的预览,我还没有找到合适的答案。我怎样才能做到这一点呢?我认为

我的代码是使用MousePresseEvent和mouseReleaseEvent在QImage上绘制线条。它的作品很好,但我想一个动态预览线出现时,我画说的线(即在MouseMoveEvent)。现在,当我松开鼠标左键时,这条线就出现了,我看不到我在画什么

我希望在移动鼠标时显示和更新线条预览,并且在释放鼠标左键时仅“固定”。与MS绘制线工具完全相同:

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

我不知道如何显示我正在绘制的线条的预览,我还没有找到合适的答案。我怎样才能做到这一点呢?

我认为这为你的问题提供了一些非常好的解决方案。例如,它展示了如何实现一个定制类,该类实际上为您提供了一个“绘图板”:

您可以在任何需要的地方使用这个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()
希望这能有所帮助!快乐编码!:)

我认为这为你的问题提供了一些非常好的解决方案。例如,它展示了如何实现一个定制类,该类实际上为您提供了一个“绘图板”:

您可以在任何需要的地方使用这个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()

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

您可以在
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()
注意,您不需要在resize事件中调用
update()
,因为它是自动调用的


我还删除了不必要的update rect调用,因为在这种情况下它几乎是无用的:当绘制非常复杂的小部件时,通常会指定一个应该在其中进行更新的矩形(特别是当执行大量计算以正确绘制所有内容并且小部件只有一小部分实际需要更新时)。在您的情况下,计算实际的更新矩形几乎比绘制小部件的所有内容花费更多的时间。

您可以在
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()
注意,您不需要在resize事件中调用
update()
,因为它是自动调用的


我还删除了不必要的update rect调用,因为在这种情况下它几乎是无用的:当绘制非常复杂的小部件时,通常会指定一个应该在其中进行更新的矩形(特别是当执行大量计算以正确绘制所有内容并且小部件只有一小部分实际需要更新时)。在您的情况下,计算实际的更新矩形几乎比绘制小部件的所有内容花费更多的时间。

谢谢您的回答,Andris,我已经看到了这个网站。我很抱歉,如果我没有说清楚,但我不是在寻找一种在画布上“涂鸦”的方法,而是使用QPainter的drawLine功能显示我正在绘制的直线的预览。它看起来像MS绘制线工具:@MrKartofel好的,对不起,我可能误解了你的问题。谢谢澄清!谢谢你的回答,安德里斯,我已经看到了这个网站。我很抱歉,如果我没有说清楚,但我不是在寻找一种在画布上“涂鸦”的方法,而是使用QPainter的drawLine功能显示我正在绘制的直线的预览。它看起来像MS绘制线工具:@MrKartofel好的,对不起,我可能误解了你的问题。谢谢澄清!感谢您的帮助,它工作得非常完美,对于代码中不必要的位的精确性,它真的很有帮助。感谢您的帮助,它工作得非常完美,对于代码中不必要的位的精确性,它真的很有帮助。