144-QPainter和Graphics/View绘图-Graphics/View绘图-视图控件QGraphicsView

视图控件QGraphicsView

视图控件QGraphicsView 用于显示场景中的图项,当场景超过视图区域时,视图会提供滚动条。QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。

视图控件QGraphicsView 继承自 QAbstractScrollArea,视图控件根据场景的尺寸提供滚动区,当视图尺寸小于场景尺寸时会提供滚动条。

用QGraphicsView 类创建视图控件对象的方法如下所示其中parent是继承自QWidget 的窗口或控件;QGraphicsScene是场景实例对象,用于设置视图控件中的场景。

from PySide6.QtWidgets import QGraphicsView

QGraphicsView(parent: Union[PySide6.QtWidgets.QWidget,NoneType]= None)-> None
QGraphicsView(scene: PySide6.QtWidgets.QGraphicsScene,parent: Union[PySide6.QtWidgets.QWidget,NoneType]= None)-> None
GraphicsView的说明

QGraphicsView在可滚动视口中可视化QGraphicsScene的内容。要使用几何项创建场景,请参阅QGraphicsScene的文档。QGraphicsView是图形视图框架的一部分。
要可视化场景,首先要构建一个QGraphicsView对象,将要可视化的场景的地址传递给QGraphicsView的构造函数。或者,您可以调用setScene()在以后的某个点设置场景。调用show()后,默认情况下,视图将滚动到场景的中心,并显示此时可见的任何项目。例如:

scene = QGraphicsScene()
scene.addText("Hello,world!")
view = QGraphicsView(scene)
view.show()

通过使用滚动条或调用centerOn(),可以显式地滚动到场景中的任何位置。通过将一个点传递给centerOn(),QGraphicsView将滚动其视口,以确保该点在视图中居中。提供了一个重载,用于滚动到QGraphicsItem,在这种情况下,QGraphicsView将确保该项的中心位于视图的中心。如果你只想确保某个区域是可见的(但不一定是居中的),你可以调用ensureVisible()。

QGraphicsView可以用于可视化整个场景,也可以仅可视化部分场景。默认情况下,当视图首次显示时(通过调用itemsBoundingRect()),会自动检测到可视化区域。要自己设置可视化区域矩形,可以调用setSceneRef()。这将适当调整滚动条的范围。请注意,尽管场景支持几乎无限的大小,但滚动条的范围永远不会超过整数(INT_MIN,INT_MAX)的范围。

QGraphicsView通过调用render()来可视化场景。默认情况下,通过使用常规QPainter和默认渲染提示将项目绘制到视口上。要更改QGraphicsView在绘制项目时传递给QPainter的默认渲染提示,可以调用setRenderHints()。
默认情况下,QGraphicsView为视口小部件提供一个常规的QWidget。您可以通过调用viewport()来访问此小部件,也可以通过调用setViewport()替换它。要使用OpenGL进行渲染,只需调用setViewport(新的QOpenGLWidget)。QGraphicsView拥有视口小部件的所有权。

QGraphicsView使用QTransform支持仿射变换。您可以将矩阵传递给setTransform(),也可以调用方便函数rotate()、scale()、translate()或shear()之一。最常见的两种变换是用于实现缩放的缩放和旋转。QGraphicsView在转换过程中使视图的中心保持固定。由于场景对齐(setAlignment()),平移视图不会对视觉产生影响。

您可以使用鼠标和键盘与场景中的项目进行交互。QGraphicsView将鼠标和按键事件转换为场景事件(继承QGraphicsSceneEvent的事件),并将它们转发到可视化场景。最终,是单个项目处理事件并对其做出反应。例如,如果单击一个可选项目,该项目通常会让场景知道它已经被选中,并且它还会重新绘制自己以显示一个选择矩形。类似地,如果您单击并拖动鼠标来移动可移动项目,那么它就是处理鼠标移动和自身移动的项目。默认情况下,项交互是启用的,您可以通过调用setInteractive()来切换它。

您还可以通过创建QGraphicsView的子类并重新实现鼠标和按键事件处理程序来提供自己的自定义场景交互。为了简化如何以编程方式与视图中的项交互,QGraphicsView提供了映射函数mapToScene()和mapFromScene((),以及项访问器items()和itemAt()。这些功能允许您在视图坐标和场景坐标之间映射点、矩形、多边形和路径,并使用视图坐标在场景中查找项目。

当使用QOpenGLWidget作为视口时,支持立体渲染。这是使用与paintGL相同的图案完成的。要启用它,请启用StereoBuffers标志。由于标志是如何在内部处理的,请在使用setDefaultFormat()创建窗口之前全局设置StereoBuffers标志。如果该标志已启用,并且硬件支持立体渲染,则drawBackground()和drawForeground(()将在每帧触发两次。调用currentTargetBuffer()以查询当前正在被提取到哪个缓冲区。

../../_images/graphicsview-view.png

使用OpenGL视口会限制使用QGraphicsProxyWidget的能力。并不是所有小部件和样式的组合都可以使用这样的设置来支持。您应该仔细测试您的UI并进行必要的调整。

GraphicsView的属性
属性描述访问功能
alignment: Alignment当整个场景可见时,此属性保持视图中场景的对齐方式
如果整个场景在视图中可见(即,没有可见的滚动条),则视图的对齐将决定场景将在视图中的何处渲染。例如,如果对齐为AlignCenter(默认设置),则场景将在视图中居中;如果对齐为(`AlignLeft
AlignTop`),则将在视图的左上角渲染场景。
backgroundBrush: PySide6.QtGui.QBrush此属性保存场景的背景笔刷。。
此属性设置此视图中场景的背景笔刷。它用于覆盖场景自身的背景,并定义drawBackground()的行为。要为此视图提供自定义背景绘制,可以重新实现drawBackground()。
默认情况下,此属性包含一个具有NoBrush图案的笔刷。
backgroundBrush()

setBackgroundBrush(brush)
cacheMode: CacheMode此属性保存缓存视图的哪些部分。
QGraphicsView可以将预先渲染的内容缓存在QPixmap中,然后将其绘制到视口中。这种缓存的目的是加快渲染速度较慢的区域的总渲染时间。例如,纹理、渐变和alpha混合的背景渲染速度可能非常慢;尤其是在变换视图的情况下。CacheBackground标志可用于缓存视图的背景。例如:
view = QGraphicsView()
view.setBackgroundBrush(QImage(“:/images/backgroundtile.png”))
view.setCacheMode(QGraphicsView.CacheBackground)
每次转换视图时,缓存都会失效。但是,当滚动时,只需要部分无效。
默认情况下,不会缓存任何内容。
cacheMode()

setCacheMode(mode)
dragMode: DragMode此属性保留在按下鼠标左键时在场景上拖动鼠标的行为。。
此属性定义了当用户单击场景背景并拖动鼠标时应该发生的情况(例如,使用指针滚动视口内容,或使用橡皮筋选择多个项目)。默认值NoDrag不起任何作用。
此行为只影响任何项目都无法处理的鼠标单击。您可以通过创建QGraphicsView的子类并重新实现mouseMoveEvent()来定义自定义行为。
dragMode()

setDragMode(mode)
foregroundBrush: PySide6.QtGui.QBrush此属性保存场景的前景笔刷。。
此属性设置此视图中场景的前景笔刷。它用于覆盖场景自己的前景,并定义drawForeground()的行为。若要为此视图提供自定义前景绘制,可以重新实现drawForeground()。
默认情况下,此属性包含一个具有NoBrush图案的笔刷。
foregroundBrush()

setForegroundBrush(brush)
interactive: bool此属性保留视图是否允许场景交互。。
如果启用,此视图将设置为允许场景交互。否则,此视图将不允许交互,并且任何鼠标或键事件都将被忽略(即,它将充当只读视图)。
默认情况下,此属性为true。
isInteractive()

setInteractive(allowed)
optimizationFlags: OptimizationFlags此属性包含可用于调整QGraphicsView的性能的标志。。
QGraphicsView使用剪裁、额外的边界矩形调整和某些其他帮助来提高常见情况下图形场景的渲染质量和性能。但是,根据所使用的目标平台、场景和视口的不同,其中一些操作可能会降低性能。
效果因旗而异;有关详细信息,请参阅OptimizationFlags文档。
默认情况下,不启用任何优化标志。
optimizationFlags()

setOptimizationFlags(flags)
renderHints: RenderHints此属性保存视图的默认渲染提示。
这些提示用于在绘制每个可见项目之前初始化QPainter。QPainter使用渲染提示来切换渲染功能,如抗锯齿和平滑像素图变换。
默认情况下会启用文本消除锯齿。
例子:
scene = QGraphicsScene()
scene.addRect(QRectF(-10,-10,20,20))
view = QGraphicsView(scene)
`view.setRenderHints(QPainter.Antialiasing
QPainter.SmoothPixmapTransform)`
view.show()
resizeAnchor: ViewportAnchor此属性保留调整视图大小时视图应如何定位场景。。
QGraphicsView使用此属性来决定在视口小部件的大小更改时如何在视口中定位场景。默认行为NoAnchor在调整大小期间保持场景的位置不变;调整大小时,视图的左上角将显示为已锚定。
请注意,当只有场景的一部分可见时(即,当有滚动条时),此属性的效果是显而易见的。否则,如果整个场景适合视图,QGraphicsScene将使用视图对齐在视图中定位场景。
resizeAnchor()

setResizeAnchor(anchor)
rubberBandSelectionMode: ItemSelectionMode此属性保留使用橡皮筋选择矩形选择项目的行为。。
此属性定义在使用RubberBandDrag拖动模式时如何选择项目。
默认值为IntersectsItemShape;选择其形状与橡胶带相交或由橡胶带包含的所有项目。
rubberBandSelectionMode()

setRubberBandSelectionMode(mode)
sceneRect: PySide6.QtCore.QRectF此属性保留此视图所显示的场景区域。。
场景矩形定义了场景的范围,在视图的情况下,这意味着可以使用滚动条导航的场景区域。
如果未设置,或者设置了空QRectF,则此属性的值与sceneRefect相同,并且会随sceneRefct而更改。否则,视图的场景矩形不受场景的影响。
请注意,尽管场景支持几乎无限的大小,但滚动条的范围永远不会超过整数(INT_MIN,INT_MAX)的范围。当场景大于滚动条的值时,可以选择使用translate()来导航场景。
默认情况下,此属性在原点处包含一个宽度和高度为零的矩形。
sceneRect()

setSceneRect(rect)
transformationAnchor: ViewportAnchor此属性保留视图在变换期间应如何定位场景。。
QGraphicsView使用此属性来决定当变换矩阵发生变化并且视图的坐标系发生变换时,如何在视口中定位场景。默认行为AnchorViewCenter可确保视图中心的场景点在变换期间保持不变(例如,旋转时,场景将显示为围绕视图中心旋转)。
请注意,当只有场景的一部分可见时(即,当有滚动条时),此属性的效果是显而易见的。否则,如果整个场景适合视图,QGraphicsScene将使用视图对齐在视图中定位场景。
transformationAnchor()

setTransformationAnchor(anchor)
viewportUpdateMode: ViewportUpdateMode此属性保存视口应如何更新其内容。。
QGraphicsView使用此属性来决定如何更新已重新曝光或更改的场景区域。通常不需要修改此属性,但在某些情况下,这样做可以提高渲染性能。有关具体详细信息,请参阅ViewportUpdateMode文档。
默认值为MinimalViewportUpdate,其中QGraphicsView将在内容更改时更新尽可能小的视口区域。
viewportUpdateMode()

setViewportUpdateMode(mode)
QGraphicsView的枚举值
  • PySide6.QtWidgets.QGraphicsView.ViewportAnchor

    此枚举描述了QGraphicsView在用户调整视图大小或转换视图时可以使用的可能锚点。

    ConstantDescription
    QGraphicsView.NoAnchor没有锚点,即视图保持场景的位置不变。
    QGraphicsView.AnchorViewCenter位于视图中心的场景点用作锚点。
    QGraphicsView.AnchorUnderMouse鼠标下方的点用作锚点。
  • PySide6.QtWidgets.QGraphicsView.CacheModeFlag

(继承enum.Flag)此枚举描述可以为QGraphicsView的缓存模式设置的标志。

ConstantDescription
QGraphicsView.CacheNone所有绘制都直接在视口上完成。
QGraphicsView.CacheBackground缓存背景。这会影响自定义背景和基于backgroundBrush属性的背景。启用此标志后,QGraphicsView将分配一个具有视口全尺寸的像素图。
  • PySide6.QtWidgets.QGraphicsView.DragMode

    此枚举描述在视口上按住并拖动鼠标时视图的默认操作。

    ConstantDescription
    QGraphicsView.NoDrag什么也没发生;鼠标事件被忽略。
    QGraphicsView.ScrollHandDrag光标变为一只指针,拖动鼠标将滚动滚动条。此模式可在交互式和非交互式模式下工作。
    QGraphicsView.RubberBandDrag将出现一条橡皮筋。拖动鼠标将设置橡皮筋的几何图形,并选中橡皮筋覆盖的所有项目。非交互式视图禁用此模式。
  • PySide6.QtWidgets.QGraphicsView.ViewportUpdateMode

    此枚举描述了当场景内容更改或暴露时,QGraphicsView如何更新其视口。

    ConstantDescription
    QGraphicsView.FullViewportUpdate当场景的任何可见部分发生更改或重新曝光时,QGraphicsView将更新整个视口。当QGraphicsView花费更多的时间来确定要画什么时,这种方法最快(例如,当重复更新非常多的小项目时)。这是不支持部分更新的视口(如QOpenGLWidget)以及需要禁用滚动优化的视口的首选更新模式。
    QGraphicsView.MinimalViewportUpdateQGraphicsView将确定需要重新绘制的最小视口区域,通过避免重新绘制未更改的区域,最大限度地减少绘制所花费的时间。这是QGraphicsView的默认模式。尽管这种方法总体上提供了最好的性能,但如果场景中有许多微小的可见更改,QGraphicsView最终可能会花费比绘图更多的时间来寻找最小的方法。
    QGraphicsView.SmartViewportUpdateQGraphicsView将试图通过分析需要重新绘制的区域来找到最佳的更新模式。
    QGraphicsView.BoundingRectViewportUpdate将重新绘制视口中所有更改的边界矩形。这种模式的优点是QGraphicsView只在一个区域中搜索更改,从而最大限度地减少了确定需要重新绘制的内容所花费的时间。缺点是没有改变的区域也需要重新绘制。
    QGraphicsView.NoViewportUpdate当场景发生变化时,QGraphicsView将永远不会更新其视口;期望用户控制所有更新。此模式禁用QGraphicsView中的所有(可能较慢)项目可见性测试,适用于需要固定帧速率或视口以其他方式从外部更新的场景。
  • PySide6.QtWidgets.QGraphicsView.OptimizationFlag

(继承enum.Flag)此枚举描述了可以在QGraphicsView中启用以提高渲染性能的标志。默认情况下,不会设置任何这些标志。请注意,设置标志通常会产生副作用,并且这种效果可能因喷漆设备和平台而异。

ConstantDescription
QGraphicsView.DontSavePainterState渲染时,QGraphicsView在渲染背景或前景以及渲染每个项目时保护绘制者状态(请参见save())。这允许您使绘制器处于更改的状态(即,您可以调用setPen()或setBrush(),而无需在绘制后恢复状态)。但是,如果项目始终恢复状态,则应启用此标志以防止QGraphicsView执行同样的操作。
QGraphicsView.DontAdjustForAntialiasing禁用QGraphicsView的抗锯齿自动调整曝光区域。在边界Rect()上渲染抗锯齿线的项最终可能会在外部渲染线的部分。为了防止渲染伪影,QGraphicsView在所有方向上将所有暴露的区域扩展2个像素。如果启用此标志,QGraphicsView将不再执行这些调整,从而最大限度地减少需要重新绘制的区域,从而提高性能。一个常见的副作用是,使用抗锯齿绘制的项目在移动时会在场景中留下绘画痕迹。
QGraphicsView.IndirectPainting从Qt 4.6开始,恢复调用QGraphicsView::drawItems()和QGraphicsScene::drawItems()的旧绘制算法。仅用于与旧代码兼容。
视图控件QGraphicsView的常用方法

视图控件的方法较多,一些常用方法如表所示

QGraphicsView的常用方法及参数类型说:明
setScene(scene:QGraphicsScene)设置场景
scene()获取场景QGraphicsScene
setSceneRect(rect:Union[QRectF,QRect])设置场景在视图中的范围
setSceneRect(x: float,y: float,w: float,h: float)设置场景在视图中的范围
sceneRect()获取场景在视图中的范围 QRectF
setAlignment(alignment: Qt.Alignment)设置场景全部可见时的对齐方式
setBackgroundBrush(brush:Union[QBrush,Qt.BrushStyle,Qt.GlobalColor,QColor,QGradient,QImage,QPixmap])设置视图背景画刷
setForegroundBrush(brush: Union[QBrusb,Qt.BrushStyle,Qt.GlobalColor,QColor,QGradient,QImage,QPixmap])设置视图前景画刷
drawBackground(painter:QPainter,rect:Union[QRectF,QRect])重写该函数,在显示前景和图项前绘制背景
drawForeground(painter: QPainter,rect: Union[QRectF,QRect])重写该函数,在显示背景和图项后绘制前景
centerOn(pos: :Union[QPointF,QPoint.QPainterPath.Element])使某个点位于视图控件中心
centerOn(x:float,y: float)使某个点位于视图控件中心
centerOn(item: QGraphicsItem)使某个图项位于视图控件中心
ensureVisible(rect: Union[QRectF,QRectJ.xmargin:int=50,ymargin: int=50)确保指定的矩形区域可见,可见时按指定的边距显 示;如不可见,滚动到最近的点
ensureVisible(x: float.y:float,w: float,h: float.xmargin:int=50,ymargin: int=50)确保指定的矩形区域可见,可见时按指定的边距显 示;如不可见,滚动到最近的点
ensureVisible(QGraphicsItem,xmargin:int=50,ymargin: int=50)确保指定的图项可见
fitInView(rect: Union[QRectF,QRect],aspectRadioMode: Qt.AspectRatioMode = Qt.IgnoreAspectRatio)以适合方式使矩形区域可见
fitInView(x:float,y: float,w: float,h: float,aspectRadioMode: Qt.AspectRatioMode = Qt.IgnoreAspectRatio)以适合方式使矩形区域可见
fitInView(item: QGraphicsItem,aspectRadioMode: Qt.AspectRatioMode=Qt.IgnoreAspectRatio)以适合方式使图项可见
render(painter: QPainter,target: Union[QRectF,QRect],source: QRect,aspectRatioMode = Qt.KeepAspectRatio)从source(视图)把图像复制到target(其他设备如 QImage)上
resetCachedContent()重置缓存
rubberBandRect()获取用鼠标框选的范围 QRect
setCacheMode(mode: QGraphicsView.CacheMode)设置缓存模式 .
setDragMode(mode; QGraphicsView.DragMode)设置鼠标拖拽模式
setInteractive(allowed:bool)设置是否是交互模式
isInteractive()获取是否是交互模式
setOptimizationFlag(flag: QGraphicsView.OptimizationFlag,enabled: bool=True)设置优化显示标识
setOptimizationFlags(flags: QGraphicsView.OptimizationFlags)设置优化显示标识
setRenderHint(hint: QPainter.RenderHint,enabled: bool=True)恋雯豆济设置提高绘图质量标识
setRenderHints(hints:QPainter.RenderHints)设置提高绘图质量标识
setResizeAnchor(QGraphicsView.ViewportAnchor)设置视图控件改变尺寸时的锚点
resizeAnchor()获取锚点
setRubberBandSelectionMode(Qt.ItemSelectionMode)设置用鼠标框选模式
setTransform(matrix: QTransform,combine: bool=False)用变换矩阵变换视图
transform()获取变换矩阵 QTransform
isTransformed()获取是否进行过变换
resetTransform()重置变换
setTransformationAnchor(QGraphicsView.ViewportAnchor)设置变换时的锚点
setViewportUpdateMode(QGraphicsView.ViewportUpdateMode)设置刷新模式
[slot]updateScene(rects: Sequence[QRectF])更新场景
[slot]updateSceneRect(rect: Union[QRectF,QRect])更新场景
[slot]invalidateScene(rect: Union[QRectF,QRect],layers: QGraphicsScene.SceneLayers= QGraphicsScene.AllLayers)使指定的场景区域进行更新和重新绘制,相当于对 指定区域进行 update()操作
setupViewport(QWidget)重写该函数,设置视口控件
scale(sx: float,sy: float)缩放
rotate(angle: float)旋转角度,瞬时针方向为正
shear(sh: float,sv:float)错切
translate(dx: float,dy:float)平移

视图控件获取图项的方法如表所示

QGraphicsView 获取图项的方法返回值的类型
itemAt(pos:QPoint)QGraphicsItem
itemAt(x:int,y:int)QGraphicsItem
items()List[QGraphicsItem]
items(pos: QPoint)List[QGraphicsItem]
items(x:int,y:int)List[QGraphicsItem]
items(x: int,y: int,w: int,h: int,mode = Qt.IntersectsItemShape)List[QGraphicsItem]
items(rect: QRect,mode: Qt.ItemSelectionMode = Qt.IntersectsItemShape)List[QGraphicsItem]
items(polygon: Union[QPolygon,Sequence[QPoint],QRect],mode: Qt.ItemSelectionMode=Qt.IntersectsItemShape)List[QGraphicsItem]
items(QPainterPath,mode: Qt.ItemSelectionMode = Qt.IntersectsItemShape)List[QGraphicsItem]887:590

视图控件中点的坐标与场景坐标互相转换的方法如表所示

场景到视图的坐标变换方法返回值类型
mapFromScene(Union[QPointF,QPoint])QPoint
mapFromScene(QRectF)QPolygon
mapFromScene(polygon: Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPolygon
mapFromScene(path:QPainterPath)QPainterPath
mapFromScene(x: float.y: float)QPoint
mapFromScene(x: float,y: float,w:float,h: float)QPolygon
mapToScene(point:QPoint)QPointF
mapToScene(rect: QRect)QPolygonF
mapToScene(Union[QPolygon,Sequence[QPoint],QRect])QPolygonF
mapToScene(QPainterPath)QPainterPath
mapToScene(x:int,y: int)QPointF
mapToScene(int,int,int,int)QPolygonF

主要方法介绍如下。

  • 给视图控件设置场景,可以在创建视图对象时设置,也可以用setScene(QGraphicsScene)方法设置;用scene()方法获取场景。
  • 用setSceneRect(rect; Union[QRectF,QRect])方法或 setSceneRect(x: float,y:float,w;float,h;float)方法设置场景在视图中的范围,用sceneRect()方法获取场景在视图中的范围,当场景的面积超过视图所显示的范围时,可用滚动条来移动场景。
  • 用setAlignment(Qt.Alignment)方法设置场景在视图控件全部可见时的对齐方式Qt.Alignment 可以取以下值,默认是 Qt.AlignCenter
    • Qt.AlignLeft
    • Qt.AlignRight
    • Qt.AlignHCenter
    • Qt.AlignJustify
    • Qt.AlignTop,
    • Qt.AlignBottom
    • Qt.AlignVCenter
    • Qt.AlignBaseline
    • Qt.AlignCenter
  • 创建视图控件的子类,并重写 drawBackground(QPainter,QRectF)函数可以在显示前景和图项之前绘制背景;
    • 重写 drawForeground(QPainter;QRectF)函数,可以在显示背景和图项之后绘制前景。
    • 场景分为背景层、图项层和前景层三层,前面的层会挡住后面的层。
  • 用setCacheMode(mode:QGraphicsView.CacheMode)方法可以设置缓存模式,参数 mode可取:
    • QGraphicsView.CacheNone(没有缓存)
    • QGraphicsView.CacheBackground(缓存背景)
  • 用setInteractive(bool)方法设置视图控件是否是交互模式在交互模式下可以接受鼠标键盘事件;
  • 用isInteractive()方法可以获取是否是交互模式用setDragMode(mode:QGraphicsViewDragMode)方法设置在视图控件中按住鼠标左键选择图项时的拖拽模式,参数 mode 可取:
    • QGraphicsView.NoDrag(忽略鼠标事件)
    • QGraphicsView.ScrollHandDrag(在交互或非交互模式下,光标变成手的形状,拖动鼠标会移动整个场景)
    • QGraphicsView.RubberBandDrag(在交互模式下可以框选图项)。
  • 用setRubberBandSelectionMode(QtItemSelectionMode)方法设置框选图项时,图项是否能被选中,其中参数 Qt ItemSelectionMode可以取:
    • QtContainsItemShapeQt.IntersectsItemShape
    • Qt.ContainsItemBoundingRect
    • Qt.IntersectsItemBoundingRect
  • 用setOptimizationFlag(flag;QGraphicsView.OptimizationFlag,enabled: bool=True)方法设置视图控件优化显示标识,参数 lag可以取:
    • QGraphicsView.DontSavePainterState(不保存绘图状态)
    • QGraphicsView.DontAdjustForAntialiasing(不调整反锯齿)
    • QGraphicsView.IndirectPainting(间接绘制)。
  • 用scale(sx; float,sy:float)方法、rotate(angle; float)方法、shear(sh; float;sv:float)方法和translate(dx:floatdy: flat)方法可以对场景进行缩放、旋转、错切和平移,
  • 用setTransform(matrix;QTransform;combine:bool=False)方法可以用变换矩阵对场景进行变换。
  • 用setResizeAnchor(QGraphicsViewViewportAnchor)方法设置视图尺寸发生改变时的错点;
  • 用setTransformationAnchor(QGraphicsViewViewportAnchor)方法设置对视图进行坐标变换时的锚点,锚点的作用是定位场景在视图控件中的位置。其中QGraphicsView.ViewportAnchor可取:
    • QGraphicsView.NoAnchor(没有锚点,场景位置不变)
    • QGraphicsView.AnchorViewCenter(场景在视图控件的中心点作为锚点)
    • QGraphicsView.AnchorUnderMouse(光标所在的位置作为错点)。
    • 如果场景在视图控件中全部可见将使用对齐设置 setAlignment(alignment:QtAlignment)的参数
  • 用setViewportUpdateMode(QGraphicsView.ViewportUpdateMode)方法设置视图刷新模式,参数 QGraphicsView,ViewportUpdateMode 可以取:
    • QGraphicsView.FullViewportUpdate
    • QGraphicsView.MinimalViewportUpdate
    • QGraphicsView.SmartViewportUpdate
    • QGraphicsView.BoundingRectViewportUpdate
    • QGraphicsView.NoViewportUpdate;
  • 可用槽函数 updateScene(rects: Sequence[QRectF])updateSceneRect(rect:Union[QRectF,QRect])或 invalidateScene(rect: UnionQGraphicsScene.SceneLayers = QGraphicsScene.[QRectF,QRect],layers:AllLayers)方法只刷新指定的区域,参数 layers 可以取:
    • QGraphicsScene.ItemLayer
    • QGraphicsScene.BackgroundLayer
    • QGraphicsScene.ForegroundLayer
    • QGraphicsScene.AllLayers
  • 用itemAt()方法可以获得光标位置处的一个图项,如果有多个图项,则获得最上面的图项;
    • 用items()方法可以获得多个图项列表,图项列表中的图项按照z值从顶到底的顺序排列。
    • 可以用矩形、多边形或路径获取其内部的图项,例如 items(QRect,mode=Qt、IntersectsItemShape)方法,参数 mode可取:
      • Qt.ContainsItemShape(图项完全在选择框内部)
      • Qt.IntersectsItemShape(图项在选择框内部和与选择框相交)
      • Qt.ContainsItemBoundingRect(图项的边界矩形完全在选择框内部)
      • Qt.IntersectsItemBoundingRect(图项的边界矩形完全在选择框内部和与选择框交叉)
  • 用mapFromScene()方法可以把场景中的一个点坐标转换成视图控件的坐标
    • mapToScene()方法可以把视图控件的一个点转换成场景中的坐标。
  • 由于QGraphicsView 继承自QWidget,因此 QGraphicsView 提供了拖拽功能Graphics/View框架也为场景图项提供拖拽支持。
    • 当视图控件接收到拖拽事件GraphicsView框架会将拖拽事件翻译成 QGraphicsSceneDragDropEvent 事件时再发送到场景,场景接管事件,再把事件发送到光标下接受拖拽的第一个图项。为了开启图项拖拽功能,需要在图项上创建一个 QDrag 对象。
  • 用setViewport(QWidget)方法可以设置视口的控件,如果不设置,会使用默认的控件。如果要使用OpenGL渲染,则需设置 setViewport(QOpenGLWidget)。
视图控件QGraphicsView信号

视图控件QGraphicsView只有一个信号 rubberBandChanged(viewportRect:QRect,fromScenePoint:QPointF,toScenePoint:QPointF),当框选的范围发生改变时发送信号。

视图控件QGraphicsView的应用实例

下面的程序首先建立视图控件的子类,创建自定义信号,信号的参数是单击鼠标或移动鼠标时光标在视图控件的位置,并重写了鼠标单击、移动事件和背景函数,然后在场景中建立一个矩形和一个圆用鼠标可以拖动矩形和圆,并在状态栏上显示鼠标拖动点的视图坐标、场景坐标和图项坐标。

image-20230308212554836

# -*- coding: UTF-8 -*-
# File date: Hi_2023/3/6 23:23
# File_name: 01- 视图控件QGraphicsView的应用实例.py


import sys
from PySide6.QtWidgets import QApplication,QWidget,QGraphicsScene,QGraphicsView,QVBoxLayout,QStatusBar,QGraphicsRectItem,QGraphicsItem,QGraphicsEllipseItem
from PySide6.QtCore import Qt.Signal,QPoint,QRectF


class myGraphicsView(QGraphicsView):  # 视图控件的子类
    point_position = Signal(QPoint)# 自定义信号,参数是光标在视图中的位置

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

    def mousePressEvent(self,event):  # 鼠标单击事件
        self.point_position.emit(event.position())# 发送信号,参数是光标位置
        super().mousePressEvent(event)

    def mouseMoveEvent(self,event):  # 鼠标移动事件
        self.point_position.emit(event.position())
        super().mouseMoveEvent(event)# 发送信号,参数是光标位置

    def drawBackground(self,painter,rectF):
        painter.fillRect(rectF,Qt.gray)# 重写背景函数,设置背景颜色


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

        self.resize(800,600)
        self.setupUI()

    def setupUI(self):
        self.graphicsView = myGraphicsView()# 视图窗口
        self.statusbar = QStatusBar()# 状态栏
        v = QVBoxLayout(self)
        v.addWidget(self.graphicsView)
        v.addWidget(self.statusbar)
        rectF = QRectF(-200,- 150,00,300)
        self.graphicsScene = QGraphicsScene(rectF)# 创建场景

        self.graphicsView.setScene(self.graphicsScene)# 视图窗口设置场景
        rect_item = QGraphicsRectItem(rectF)# 以场景为坐标创建矩形

        rect_item.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)# 标识
        self.graphicsScene.addItem(rect_item)# 在场景中添加图项
        rectF = QRectF(-40,-40,80,80)
        ellipse_item = QGraphicsEllipseItem(rectF)# 以场景为坐标创建椭圆
        ellipse_item.setBrush(Qt.green)# 设置画刷

        ellipse_item.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)# 标识
        self.graphicsScene.addItem(ellipse_item)# 在场景中添加图项
        self.graphicsView.point_position.connect(self.mousePosition)# 信号与槽的连接

    def mousePosition(self,point):  # 槽函数
        template ="view坐标:{},{}   scene坐标:{},{}   item坐标:{},{}"
        point_scene = self.graphicsView.mapToScene(point)# 视图中的点映射到场景中
        item = self.graphicsView.itemAt(point)# 获取视图控件中的图项

        # item = self.graphicsScene.itemAt(point_scene,self.graphicsView.transform())# 场景中图项

        if item:
            point_item = item.mapFromScene(point_scene)# 把场景坐标转换为图项坐标
            string = template.format(point.x(),point.y(),point_scene.x(),point_scene.y(),point_item.x(),point_item.y())

        else:
            string = template.format(point.x(),point.y(),point_scene.x(),point_scene.y(),"None","None")
            self.statusbar.showMessage(string)# 在状态栏中显示坐标信息


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyWindow()

    win.show()
    sys.exit(app.exec())

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值