You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让PyQt5 QGraphicsScene中的文本随窗口同步缩放

实现QGraphicsScene文本随窗口同步缩放

核心问题

现有代码无法自适应的原因:

  • 未给QGraphicsScene设置固定场景边界,场景会根据内容自动计算渲染范围
  • 窗口尺寸变化时未调整视图缩放矩阵,场景始终按1场景单位对应1屏幕像素的规则渲染,固定尺寸的字体不会随窗口大小变化
  • 原代码字体设置存在属性冲突,同时调用setPointSize、setPixelSize、重复设置字重会导致配置被覆盖。

实现方案

不需要单独监听文本尺寸动态修改字体,利用QGraphicsView的视图缩放能力即可让所有场景图元(包括文本、图形、图片)同步随窗口缩放,步骤如下:

  • 初始化场景时明确设置固定场景矩形,和业务布局的尺寸对齐
  • 自定义QGraphicsView子类,重写resizeEvent事件,每次窗口大小变化时调用fitInView()将整个场景缩放到适配当前视图的尺寸,可按需选择是否保持原始宽高比。

完整可运行代码

"""Draw text on a QGraphicsScene with auto resize"""

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
app = QApplication([])


class AdaptiveGraphicsView(QGraphicsView):
    def __init__(self, scene, parent=None):
        super().__init__(scene, parent)
        # 开启抗锯齿提升显示效果
        self.setRenderHint(QPainter.Antialiasing)
        # 场景居中显示
        self.setAlignment(Qt.AlignCenter)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        # 场景自适应视图大小,KeepAspectRatio=保持宽高比不拉伸,IgnoreAspectRatio=拉伸填满窗口
        self.fitInView(self.scene().sceneRect(), Qt.KeepAspectRatio)


class MyScene(QMainWindow):

    rotated_layout = {
        'Chips': [
            {'Chip': 0, 'X': 256, 'Y': 0, 'Orientation': 'RtLBtT'},
            {'Chip': 1, 'X': 0, 'Y': 0, 'Orientation': 'RtLBtT'},
            {'Chip': 2, 'X': 0, 'Y': 256, 'Orientation': 'LtRTtB'},
            {'Chip': 3, 'X': 256, 'Y': 256, 'Orientation': 'LtRTtB'}
        ],
        'Width': 512,
        'Height': 512
    }

    def __init__(self, parent=None):
        super().__init__(parent)

        scene = QGraphicsScene()
        # 设置固定场景边界
        scene.setSceneRect(0, 0, self.rotated_layout['Width'], self.rotated_layout['Height'])

        # 初始化字体,避免属性冲突
        font = QFont("Times")
        font.setPixelSize(150)
        font.setBold(True)

        for i, chip in enumerate(self.rotated_layout["Chips"]):
            X, Y = chip['X'], chip['Y']
            t = QGraphicsTextItem(str(i))
            t.setPos(256 / 2 + X, 256 / 2 + Y)
            t.setFont(font)
            scene.addItem(t)

        gv = AdaptiveGraphicsView(scene)
        self.setCentralWidget(gv)


if __name__ == '__main__':
    graph = MyScene()
    graph.show()
    app.exec()

补充说明

  • 该方案会让场景内所有图元同步缩放,不需要针对文本单独写逻辑
  • 如果需要实现文本固定屏幕大小、不随场景缩放的效果(类似地图标注),给文本图元设置QGraphicsItem.ItemIgnoresTransformations标志即可
  • 如果需要添加滚轮缩放、拖拽平移等交互,直接修改视图的transform矩阵即可,文本会自动跟随缩放。

内容的提问来源于stack exchange,提问作者CiaranWelsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:33:44