如何让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
相关产品推荐
相关产品推荐

