PySide6 QGraphicsTextItem文本外描边绘制无限循环问题求助
解决QGraphicsTextItem描边导致paint无限循环的问题
问题根源
你当前的实现每次在paint()方法里修改文本格式并合并到文档,修改文档会触发图形项的update()请求,导致paint()被反复调用,形成无限循环。即便后来重置了描边格式,这个修改动作依然会触发更新,让paint持续执行。
高效实现方案
正确的思路是不在paint中修改文档内容或格式,而是利用QPainter的绘制状态分层绘制:先绘制粗描边,再绘制原文本。这种方式不会修改文本项的内部文档,也就不会触发不必要的重绘循环。
修改后的完整代码:
import sys from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * class OutlinedGraphicsTextItem(QGraphicsTextItem): def __init__(self, text="", parent=None): super().__init__(text, parent) # 初始化时设置字体,避免paint中重复操作 self.setFont(QFont("", 80)) # 可自定义描边属性 self.outline_color = Qt.red self.outline_width = 10 def paint(self, painter, option, widget): # 保存painter原始状态,防止影响其他绘制逻辑 painter.save() # 第一步:绘制文本描边 outline_pen = QPen(self.outline_color, self.outline_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) painter.setPen(outline_pen) # 用drawText绘制描边层 painter.drawText(self.boundingRect(), self.defaultTextOption(), self.toPlainText()) # 第二步:绘制原始文本,覆盖在描边上 painter.setPen(self.pen()) super().paint(painter, option, widget) # 恢复painter初始状态 painter.restore() # 示例使用 if __name__ == "__main__": app = QApplication(sys.argv) text_item = OutlinedGraphicsTextItem("Hello, World!") scene = QGraphicsScene() scene.addItem(text_item) view = QGraphicsView(scene) view.show() sys.exit(app.exec_())
核心优化点
- 移除文档修改操作:把字体设置移到
__init__中只执行一次,避免在paint里修改文档触发重绘循环。 - 分层绘制逻辑:通过两次绘制(描边+原文本)实现效果,完全不改动文本项的内部数据,不会触发额外更新。
- Painter状态管理:用
save()和restore()隔离当前绘制的状态,避免干扰其他图形项的绘制。
扩展建议
如果需要动态调整描边颜色或宽度,可以给类添加对应的setter方法,在方法内调用update()主动触发重绘,比如:
def set_outline_color(self, color): self.outline_color = color self.update() def set_outline_width(self, width): self.outline_width = width self.update()
这样只有在属性变更时才会重绘,保证性能。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

