QGraphicsView简介
QGraphicsView是一个用于显示QGraphicsScene场景的部件。它提供一个可以滚动显示QGraphicsScene内容的窗口。
可以在构建QGraphicsView的时候,可以QGraphicsScene场景对象作为参数,或者在构建之后使用setScene()来设置场景。在调用show()函数后,默认情况下,视图将滚动到场景的中心并显示此时可见的所有图元,例如:
1 2 3 4 | scene =QGraphicsScene() scene.addText('Hello, world!) view = QGraphicsView(scene) view.show() |
可以使用滚动条或者调用centerOn()显示地滚动到场景的任何位置。在调用centerOn()时,视图会把传入的参数作为中心点以确保该点位于视图的中心。
QGraphics可用于显示整个场景或者场景的一部分。在默认情况下,第一次显示时,会通过调用QGraphicsScene.itemsBoundingRect()来自动检测可视区域,调用setSceneRect()可以自己设置可视区域。
QGraphicsView通过调用render()还可视化场景。默认情况下,根据缺省的渲染提示使用QPainter将图元渲染到视口上。调用setRenderHints()可更改QGraphicsView传递给QPainter的渲染提示。
默认情况下,QGraphicsView的视口窗口部件为一个常规的QWidget,可以通过viewport() 来访问这个部件,也可以通过调用setViewport()来替换它。如果要使用OpenGL 来渲染,只需调用setViewport()将视口的窗口部件设置为QOpenGLWidget对象即可。
QGraphicsView支持仿射变换,使用setTransform()设置其变换矩阵。最常用的两种变换是缩放和旋转,可分别调用roatate()和scale()来完成。
可以使用鼠标和键盘与场景中的图元进行交互。QGraphicsView将鼠标和键盘事件转换成场景事件,并将其转发到可视化场景。最后,处理事件并对事件做出反应的是单个图元。例如,如果单击一个可选图元,则该图元通常会让场景知道它已被选中,并且它还将重绘自身以显示选择矩形。可以通过创建QGraphicsView的子类并重新实现鼠标和键事件处理程序来提供自己的自定义场景交互。
QGraphicsView常用方法:
- setScene(): 设置场景,如果场景已经被设置到视图中,则什么都不做。
- scene(): 返回当前视图中的可视化场景对象。
- setCacheMode(): 设置缓存模式,这个属性控制视图的哪一部分存储在缓存中,QGraphicsView可以预存一些内容在QPixmap中,然后被绘制到视口上,这样做的目的是加速整体区域重绘的速度。默认情况不使用缓存模式。
- cacheMode(): 返回缓存模式。
- setViewportUpdateMode(): 设置视口更新模式,QGraphicsView 使用这个属性来决定当场景改变或者暴露时候如何刷新场景的区域,通常不需要修改这个属性,但是在有些情况下做这个工作可以改进绘图性能。
- setTransformationAnchor(): 设置视口变换的锚点,这个属性控制当视图做变换时应该如何摆放场景的位置。默认情况是在变换时保持视图的中心点不变。
- scale(): 缩放当前的视图。
- rotate(): 顺时针旋转当前视图。
- translate(): 平移当前的视图。
- setTransform():设置视图当前的转换矩阵。
- transform():获得视图当前的转换矩阵。
- shear(): 剪切当前视图变换。
QGraphicsView常用信号:
- rubberBandChanged: 橡皮筋(rubber band)矩形发生改变时,发生该信号。
QGraphicsView类继承关系:

测试QGraphicsView
在测试代码中,在场景中添加一个文本图元,一个填充的椭圆和一个矩形,然后创建一个变换操作对话框,调用QGraphicsView的rotate()和scale()函数来演示旋转和缩放。完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | import sys from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtGui import QPen, QBrush, QFont, QTransform from PyQt5.QtWidgets import (QApplication, QMainWindow, QDialog, QLabel, QSlider, QMenuBar, QMenu, QAction, QFormLayout, QGraphicsScene, QGraphicsView) class TransDialog(QDialog): def __init__(self, view, parent=None): super(TransDialog, self).__init__(parent) self.view = view #操作窗口标题 self.setWindowTitle('视口变换操作') self.initUi() def initUi(self): fLayout = QFormLayout() #旋转 sdrRotate = QSlider(Qt.Horizontal) sdrRotate.setRange(-360, 360) sdrRotate.setPageStep(5) sdrRotate.setValue(0) sdrRotate.valueChanged.connect(self.onRotateValueChanged) fLayout.addRow('旋转', sdrRotate) #缩放 sdrScale = QSlider(Qt.Horizontal) sdrScale.setRange(0, 100) sdrScale.setPageStep(5) sdrScale.setValue(50) sdrScale.valueChanged.connect(self.onScaleValueChanged) fLayout.addRow('缩放', sdrScale) self.setLayout(fLayout) def onRotateValueChanged(self, value): #是个累积效应,先对变化矩阵进行复位操作 self.view.setTransform(QTransform()) self.view.rotate(value) def onScaleValueChanged(self, value): s = 0.5 + value / 100.0 #是个累积效应,先对变化矩阵进行复位操作 self.view.setTransform(QTransform()) self.view.scale(s, s) class DemoGraphicsView(QMainWindow): def __init__(self, parent=None): super(DemoGraphicsView, self).__init__(parent) # 设置窗口标题 self.setWindowTitle('实战PyQt5: QGraphicsView Demo!') # 设置窗口大小 self.resize(480, 360) self.initUi() def initUi(self): #菜单条 menuBar = self.menuBar() menuFile = menuBar.addMenu('文件') aTrans = QAction('变换操作', self) aTrans.triggered.connect(self.onTransDialog) aReset = QAction('复位',self) aReset.triggered.connect(self.onReset) aExit = QAction('退出', self) aExit.triggered.connect(self.close) menuFile.addAction(aTrans) menuFile.addAction(aReset) menuFile.addSeparator() menuFile.addAction(aExit) #场景部分 scene = QGraphicsScene() scene.addText('Hello Graphics View', QFont(self.font().family(), 24)) scene.addEllipse(0, 80, 200, 120, QPen(Qt.black), QBrush(Qt.blue)) scene.addRect(220, 80, 200, 160, QPen(Qt.red)) self.view = QGraphicsView() self.view.setScene(scene) self.setCentralWidget(self.view) def onTransDialog(self): dlg = TransDialog(self.view, self) dlg.exec() def onReset(self): self.view.setTransform(QTransform()) if __name__ == '__main__': app = QApplication(sys.argv) window = DemoGraphicsView() window.show() sys.exit(app.exec()) |
运行结果如下图:

测试QGraphicsView
本文知识点
- QGraphicsView设置场景的两种办法;
- QGraphicsView空间变换操作;
- QGraphicsView空间变换的合成作用,以及如何复原空间变换。
前一篇: 实战PyQt5: 086-图元类QGraphicsItem