Qt5 带有图层的涂鸦 - QPaintDevice:无法破坏正在绘制的设备

Posted

技术标签:

【中文标题】Qt5 带有图层的涂鸦 - QPaintDevice:无法破坏正在绘制的设备【英文标题】:Qt5 scribble with layers - QPaintDevice: cannot destroy device that is being painted 【发布时间】:2016-10-05 06:26:26 【问题描述】:

我正在尝试为多层图像重新实现the scribble demo app。我正在努力在场景中绘制像素图,因为 Painter 抱怨说它早早地被破坏了。

QPaintDevice:无法销毁正在绘制的绘图设备

能否请您帮我修复我的代码,以便您可以用红笔在 roilayer 像素图上绘图,并且该图层开始透明。

#!/usr/bin/python3

import sys
import os
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
from PyQt5.QtGui import QPixmap, QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QRect


class Main(QGraphicsView):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Scribble with layers")
        self.scene = QGraphicsScene()
        self.setScene(self.scene)
        self.image = QImage('sample/test.bmp')
        self.imlayer = QGraphicsPixmapItem(QPixmap.fromImage(self.image))
        self.roilayer = QGraphicsPixmapItem(QPixmap(self.image.size()))
        self.addlayer(self.imlayer)
        self.addlayer(self.roilayer)
        self.drawing = False
        self.lastPoint = None
        self.pencolour = Qt.red
        self.penwidth = 2
        self.show()

    def addlayer(self, layer):
        self.scene.addItem(layer)
        self.updateviewer()

    def updateviewer(self):
        self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)

    def mousePressEvent(self, event):
        # print(event.modifiers())
        if event.button() == Qt.LeftButton:
            self.lastPoint = event.pos()
            self.drawing = True

    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) and self.drawing:
            self.drawlineto(event.pos())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.drawing:
            self.drawlineto(event.pos())
            self.drawing = False

    def drawlineto(self, position):
        pixmap = self.roilayer.pixmap()
        painter = QPainter(pixmap)
        painter.setPen(QPen(self.pencolour, self.penwidth, Qt.SolidLine,
                Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(self.lastPoint, position)
        self.imlayer.setPixmap(pixmap)
        self.modified = True

        rad = self.penwidth / 2 + 2
        self.update(QRect(self.lastPoint, position).normalized().adjusted(-rad, -rad, +rad, +rad))
        self.lastPoint = position


if __name__ == '__main__':
    app = QApplication([])
    main = Main()
    sys.exit(app.exec_())

【问题讨论】:

尝试在 self.imlayer.setPixmap(pixmap) 之前添加行 painter.end() 让 Qt 知道你已经完成了绘画。 谢谢。我不敢相信它这么简单,我发现 Painter 的文档令人困惑。 嗨,Jbbiomed。你能给我一些指导来让这个代码工作吗?我正在构建一个简单的绘画应用程序。我尝试将painter.end() 添加为@G.M.之前说过,但它对我不起作用。 【参考方案1】:

我遇到了同样的问题。解决方案是对这部分代码执行以下操作:

    def drawlineto(self, position):
        pixmap = self.roilayer.pixmap()
        painter = QPainter()
        painter.begin(pixmap)
        painter.setPen(QPen(self.pencolour, self.penwidth, Qt.SolidLine,
            Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(self.lastPoint, position)
        painter.end()
        self.imlayer.setPixmap(pixmap)
        self.modified = True

【讨论】:

以上是关于Qt5 带有图层的涂鸦 - QPaintDevice:无法破坏正在绘制的设备的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 带有图层的 UIScrollVIew

带有图层的 iOS 6 上的样式控件是错误的? (来自iOS7)

沿着图层的特定路径快速制作动画

arcMap 配置图层

将 WFS 与带有传单 1.0 的图层一起使用会产生错误

ps:图层的选择