Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PySide2 raises error, "QPaintDevice: Cannot destroy paint device that is being painted" [duplicate]

Tags:

python

pyside2

I'm trying to paint something on a QPixmap, but it throws an error during cleanup.

from PySide2.QtGui import QPixmap, QPainter
from PySide2.QtWidgets import QApplication

app = QApplication()
width = 200
height = 100
pixmap = QPixmap(width, height)
painter = QPainter(pixmap)
painter.drawLine(0, 0, 100, 100)
print('Done.')

When I run that, I see the 'Done' message, and then an error.

Done.
QPaintDevice: Cannot destroy paint device that is being painted

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

I've seen some similar questions with the same error, but it's not clear what's causing the error or how to avoid it.

like image 354
Don Kirkby Avatar asked Sep 03 '25 02:09

Don Kirkby


1 Answers

After experimenting, it seems that the painter has to clean up before the pixmap does, otherwise you get the error. For example, this works without error.

from PySide2.QtGui import QPixmap, QPainter
from PySide2.QtWidgets import QApplication

app = QApplication()
width = 200
height = 100
pixmap = QPixmap(width, height)
painter = QPainter(pixmap)
painter.drawLine(0, 0, 100, 100)
print('Done.')

del painter
del pixmap

You can also tell the painter to clean up without destroying it. Just tell it that you've finished painting by calling end().

from PySide2.QtGui import QPixmap, QPainter
from PySide2.QtWidgets import QApplication

app = QApplication()
width = 200
height = 100
pixmap = QPixmap(width, height)
painter = QPainter(pixmap)
painter.drawLine(0, 0, 100, 100)
print('Done.')

painter.end()

There are some other things that avoid the error for mysterious reasons. For example, this avoids the error.

from PySide2.QtGui import QPixmap, QPainter
from PySide2.QtWidgets import QApplication

app = QApplication()
width = 200
height = 100
pixmap = QPixmap(width, height)
painter = QPainter(pixmap)
painter.device()  # <-- No idea why this helps!
painter.drawLine(0, 0, 100, 100)
print('Done.')

In summary, just make sure that the painter cleans up before the pixmap does. I would recommend either using the painter in a smaller scope than the pixmap or explicitly calling painter.end().

like image 137
Don Kirkby Avatar answered Sep 05 '25 18:09

Don Kirkby