Qt QGraphicsView部件缩小时,QImage转QPixMap出现绘制伪影
MDraw部件缩小时绘制伪影的解决方案
问题现象
实现的MDraw部件在窗口尺寸扩大时绘制正常,但缩小时会出现绘制伪影(残留旧的绘制内容)。
原代码
class MDraw(QtWidgets.QGraphicsView): def __init__(self, parent): super(MDraw, self).__init__(parent) self.data = None self.width = 0 self.height = 0 def resizeEvent(self, event): self.width = event.size().width() self.height = event.size().height() self.draw(self.data) def draw(self, indata): self.image = QImage(self.width, self.height, QImage.Format_ARGB32) self.image = QImage(self.width, self.height, QImage.Format_Grayscale8) self.image = QImage(self.width, self.height, QImage.Format_Alpha8) self.image = QImage(self.width, self.height, QImage.Format_RGB32) qpainter = QPainter(self.image) bbush = QBrush(QColor(90,0,0)) qpainter.setBrush(bbush) qpainter.drawRect(20, 20, 80, 80) qpainter.end() self.pixmap = QPixmap.fromImage(self.image) self.pixmapItem = QGraphicsPixmapItem(self.pixmap) scene = QGraphicsScene() scene.addItem(self.pixmapItem) self.setScene(scene)
问题原因
- QImage未初始化背景:创建QImage后没有填充背景色,新图像的像素为未初始化的随机值,缩小时这些脏像素会被显示出来。
- 重复创建QGraphicsScene:每次绘制都新建Scene,不仅造成资源浪费,还可能导致视图更新不及时,残留旧内容。
- 冗余的QImage创建:代码中连续创建4次QImage,前3次被直接覆盖,完全无效。
修复后的代码
class MDraw(QtWidgets.QGraphicsView): def __init__(self, parent): super(MDraw, self).__init__(parent) self.data = None # 初始化一次Scene,避免重复创建 self.scene = QGraphicsScene(self) self.setScene(self.scene) self.pixmap_item = None def resizeEvent(self, event): width = event.size().width() height = event.size().height() self.draw(width, height) def draw(self, width, height): # 只创建一次需要的格式的QImage self.image = QImage(width, height, QImage.Format_RGB32) # 填充背景色(这里用白色,可根据需求调整) self.image.fill(QColor(255, 255, 255)) qpainter = QPainter(self.image) bbush = QBrush(QColor(90, 0, 0)) qpainter.setBrush(bbush) qpainter.drawRect(20, 20, 80, 80) qpainter.end() self.pixmap = QPixmap.fromImage(self.image) # 复用pixmap_item,避免重复创建 if self.pixmap_item: self.pixmap_item.setPixmap(self.pixmap) else: self.pixmap_item = QGraphicsPixmapItem(self.pixmap) self.scene.addItem(self.pixmap_item) # 确保视图更新 self.viewport().update()
关键修复点
- 在
__init__中提前初始化QGraphicsScene,复用该场景而非每次绘制新建。 - 创建
QImage后立即用fill()填充背景色,清除脏像素。 - 复用
QGraphicsPixmapItem,通过setPixmap()更新内容,减少对象创建开销。 - 调用
viewport().update()强制视图重绘,确保尺寸变化时界面及时刷新。
内容的提问来源于stack exchange,提问作者user794667
相关产品推荐
相关产品推荐

