146-QPainter和Graphics/View绘图-Graphics/View绘图-图项QGraphicsItem

图项QGraphicsItem

QGraphicsItem类是 QGraphicsScene 中所有图项的基类用于编写自定义图项,包括定义图项的几何形状、碰撞检测、绘图实现,以及通过其事件处理程序进行图项的交互,继承自QGraphicsItem 的类有:

  • QAbstractGraphicsShapelfem
  • QGraphicsEllipseltem
  • QGraphicsItemGroup
  • QGraphicsLineltem
  • QGraphicsPathItem
  • QGraphicsPixmapItem
  • QGraphicsPolygonItem
  • QGraphicsRectItem
  • QGraphicsSimpleTextItem。

图项支持鼠标拖放、滚轮右键菜单按下释放、移动、双击以及键盘等事件,进行分组和碰撞检测,还可以给图项设置数据

用QGraphicsItem类创建图项实例对象的方法如下,其中parent是QGraphicsItem的实例,在图项间形成父子关系。

from PySide6.QtWidgets import QGraphicsItem

QGraphicsItem(parent: Union[PySide6.QtWidgets.QGraphicsItem,NoneType]= None)-> None
图项的常用方法如表所示
QGraphicsItem的方法及参数类型说一明
paint(painter:QPainter, option: QStyleOptionGraphicsItem, widget: QWidget=None)重写该函数,绘制图形
boundingRect()重写该函数,返回边界矩形QRectF
itemChange(change: QGraphicsIten.GraphicsltemChange, value:Any)重写该函数,以便在图项的状态发生改变时做出 响应
advance(phase)重写该函数,用于简单动画,由场景的advance()调 用。phase=0时通知图项即将运动,phase=1时可 以运动
setCacheMode(mode: QGraphicsItem, CacheMode, cacheSize:QSize=Default(QSize))设置图项的级冲模式
childItems()获取子项列表 List[QGraphicsItem]
childrenBoundingRect()获取子项的边界矩形
clearFocus()清除焦点
collidesWithltem(Other: QGraphicsltem,mode:Qt.ItemSelectionMode=Qt.IntersectsltemShape)获取是否能与指定的图项发生碰撞
collidesWithPath(path:QPainterPath,mode:Qt.ItemSelectionMode=Qt.IntersectsItemShape)获取是否能与指定的路径发生碰撞
collidingItems(mode= Qt.IntersectsItemShape)获取能发生碰撞的图项列表
contains(Union[QPointF,QPoint])获取图项是否包含某个点
grabKeyboard()、ungrabKeyboard()接受、不接受键盘的所有事件
grabMouse()、ungrabMouse()接受、不接受鼠标的所有事件
isActive()获取图项是否活跃
isAncestorOf(QGraphicsItem)获取图项是否是指定图项的父辈
isEnabled()获取是否激活
isPanel()获取是否面板
isSelected()获取是否被选中
isUnderMouse()获取是否处于光标下
parentItem()获取父图项
resetTransform()重置变换
scene()获取图项所在的场景
sceneBoundingRect()获取场景的范围
scenePos()获取在场景中的位置 QPointF
sceneTransform()获取变换矩阵 QTransform
setAcceptDrops(bool)设置是否接受鼠标释放事件
setAcceptedMouseButtons(Qt.MouseButton)设置可接受的鼠标按钮
setActive(bool)设置是否活跃
setCursor(Union[QCursor,Qt.CursorShape])设置光标形状
unsetCursor()重置光标形状
setData(key:int,value:Any)给图项设置数据
data(key:int)获取图项存储的数据
setEnabled(bool)设置图项是否激活
setFlag(QGraphicsItem.GraphicsItemFlag,enabled=True)设置图项的标识
setFocus(focusReason=Qt.OtherFocusReason)设置焦点
setGroup(QGraphicsItemGroup)将图项加入到组中
group()获取图项所在的组
setOpacity(opacity: float)设置不透明度
setPanelModality(QGraphicsItem.PanelModality)设置面板的模式
setParentItem(QGraphicsltem)设置父图项
setPos(Union[QPointF,QPoint])setPos(x: float,y: float)设置在父图项坐标系中的位置
setX(float)、setY(float)设置在父图项中的x和y坐标
pos()获取图项在父图项中的位置 QPointF
x()、y()获取×坐标、获取y坐标
setRotation(angle:float)设置沿z轴顺时针旋转角度(°)
setScale(scale:float)设置缩放比例系数
moveBy(dx:float,dy: float)设置移动量
setSelected(selected:bool)设置是否选中
setToolTip(str)设置提示信息
setTransform(QTransform,combine=False)设置矩阵变换
setTransformOriginPoint(origin: Union[QPointF,QPoint])设置变换的中心点
setTransformOriginPoint(ax:float,ay:float)设置变换的中心点
set Transformations(Sequence[QGraphicsTransform])设置变换矩阵
transform()获取变换矩阵 QTransform
transformOriginPoint()获取变换原点QPointF
setVisible(bool)设置图项是否可见
show()、hide()显示图项、隐藏图项,子项也隐藏
isVisible()获取是否可见
setZValue(float)设置z值
zValue()获取z值
shape()重写该函数,返回图形的绘图路径 QPainterPath,用于碰撞检测等
stackBefore(QGraphicsItem)在指定的图项前插入
isWidget()获取图项是否是图形控件 QGraphicsWidget
isWindow()获取图形控件的窗口类型是否是Qt.Window
window()获取图项所在的图形控件 QGraphicsWidget
topLevelWidget()获取顶层图形控件 QGraphicsWideet
topLevelItem()获取顶层图项(没有父图项)
update(rect: Union[QRectF,QRect]= Default(QRectF))更新指定的区域
update(x: float,y: float,width: float,height: float)更新指定的区域
在图项场景间的映射方法如表所示
从其他图顶映射
图项坐标的映射方法及参数类型返回值类型
mapFromltem(item:QGraphicsltem,path:QPainterPath)QPainterPath
mapFromItem(item: QGraphicsltem,point:Union[QPointF,QPoint])QPointF
mapFromItem(item: QGraphicsItem,polygon:Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPolygonF
mapFromItem(item: QGraphiesltem.rect: Union[QRectF.QRect])QPolygonF
napFromItem(item:QGraphicsltem,x:float,y: float)QPointF
mapFromItem(item:QGraphicsltem,x: float,y: float,w: float,h: float)QPolygonF
mapRectFromItem(item:QGraphicsltem,rect:Union[QRectF,QRect])QRectF
mapRectFromItem(item: QGraphicsltem, x; float, y: float, w: float, h: float)QRectF
从父图项映射
图项坐标的映射方法及参数类型返回值类型
mapFromParent(path: QPainterPath)QPainterPath
mapFromParent(point:Union[QPointF,QPoint])QPointF
mapFromParent(polygon:Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPoIygonF
mapFromParent(rect:Union[QRectF,QRect])QPolygonF
mapFromParent(x:float,y:float)QPointF
mapFromParent(x:float,y: float,w: float,h: float)QPolygonF
mapRectFromParent(rect: Union[QRectF,QRect])QRectF
mapRectFromParent(x:float,y:float,w: float,h: float)QRectF
从场景映射
图项坐标的映射方法及参数类型返回值类型
mapFromScene(path: QPainterPath)QPainterPath
mapFromScene(point: Union[QPointF,QRoint])QPointF
mapFromScene(polygon: Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPolygonF
mapFromScene(rect:Union[QRectF,QRect])QPolygonF
mapFromScene(x: float,y:float)QPointF
mapFromScene(x: float,y:float,w: float,h: float)QPolygonF
mapRectFromScene(rect;Union[QRectF,QRect])QRectF
mapRectFromScene(x: float,y: float,w: float,h:float)QRectF
映射到父图项
图项坐标的映射方法及参数类型返回值类型
mapToParent(path:QPainterPath)QPainterPath .
mapToParent(point:Union[QPointF,QPoint])QPointF
mapToParent(polygon: Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPolygonF
mapToParent(rect:Union[QRectF,QRect])QPolygonF
mapToParent(x:float,y:float)QPointF
mapToParent(x: float,y: float,w: float,h;float)QPolygonF
mapRectToParent(rect:Union[QRectF,QRect])QRectF
mapRectToParent(x: float,y;float,w; float,h:float)QRectF
映射到场景
图项坐标的映射方法及参数类型返回值类型
mapToScene(x: float,y: float)QPointF
mapToScene(x:loat.y: float.w: float,h: loat)QPolygonP
mapRect ToScene(rect: Union[QReetF,QRect])QRectF
mapRect ToScene(x:float,y: float.w: float.h: float)QRectF
mapToScene(path: QPainterPath)QPainterPath
mapToScene(point:Union[QPointF,QPoint])QPointF
mapToScene(polygon: Union[QPolygonF,Sequence[QPointF],QPolygon,QRectF])QPolygonF
mapToScene(rect:Union[QRectF,QRect])QPolygonF
主要方法介绍
  • 用户需要从QGraphicsItem 类继承并创建自己的子图项类,需要在子类中重写paint(painter: QPainter,option: QStyle(ptionGraphicsItem,widget:QWidget 一None)函数和 boundingRect()函数

    • boundingRect()函数的返回值是图项的范围QRectF。
    • paint()函数会被视图控件调用需要在paint()函数中用QPainter绘制图形图形是在图项的局部坐标系中绘制的。
      • QPainter 的钢笔宽度初始值是1,
      • 画刷的颜色是QPalette.window,
      • 线条的颜色是 QPalette text,
      • QStyleOptionGraphicsItem 是绘图选项,
      • QWidget 是指将绘图绘制到哪个控件上如果为 None,则绘制到缓存上
    • boundingRect()函数需要返回QRectF,用于确定图项的边界。paint()中绘制的图形不能超过边界矩形
  • 用setFlag(QGraphicsItem.GraphicsItemFlag,enabled=True)方法设置图项的标志,其中参数QGraphicsItemGraphicsItemFlag 可取的值如表所示

    QGraphicsltem.GraphicsltemFlag的取值说 明
    QGraphicsItem.ItemIsMovable可移动
    QGraphicsItenm.ItemlsSelectable可选择
    QGraphicsItem.ItemIsFocusable可获得键盘输入焦点、鼠标按下和释放事件
    QGraphicsItem.ItemClipsToShape剪切自己的图形,在图项之外不能接收鼠标拖放和 悬停事件
    QGraphicsItem.ItemClipsChildrenToShape剪切子类的图形,子类不能在该图项之外绘制
    QGraphicsItem.ItemIgnoresTransformations忽略来自父图项或视图控件的坐标变换,例如文字 可以保持水平或竖直,文字比例不缩放
    QGraphicsItem.ItemIgnoresParentOpacity使用自己的透明设置,不使用父图项的透明设置
    QGraphicsltem ItermDoesntPropagateOpacityIoChildren图项的透明设置不影响其子图项的透明值
    QGraphicsItem.ItemStacksBehindParent放置于父图项的后面而不是前面
    QGraphicsltem,ItemHasNoContents图项中不绘制任何图形,调用paint()方法也不起任 何作用
    QGraphicsItem.ItemSendsGeometryChanges该标志使itemChange()函数可以处理图项几何形 状的改变,例如ItemPositionChange、 ItemScaleChange、ItemPositionHasChanged、Item TransformChange、ItemTransformHasChanged、 ItemRotationChange、 ItemRotationHasChanged、 ItemScaleHasChanged、Item TransformOriginPointChange、ItemTransformOriginPointHasChanged
    QGraphicsItem.ItemAcceptslnputMethod图项支持亚洲语言
    QGraphicsItem.ItemNegativeZStacksBehindParent如果图项的z值是负值,则自动放置于父图项的后 面,可以用setZValue()方法切换图项与父图项的 位置
    QGraphicsItem.ItemIsPanel图项是面板,面板可被激活和获得焦点,在同一时间 只有一个面板能被激活,如果没有面板,则激活所有 非面板图项
    QGraphicsItem.ItemSendsScenePositionChanges该标志是itemChange()函数可以处理图项在视图控 件中的位置变化事件ItemScenePositionHasChanged
    QGraphicsItem.ItemContainsChildrenInShape该标志说明图项的所有子图项在图项的形状范围内 绘制,这有利于图形绘制和碰撞检测。与 ItemContainsChildrenInShape标志相比,该标志不是 强制性的
  • 重写itemChange(change:QGraphicsItem,GraphicsItemChange,value: Any)函数可以在图项的状态发生改变时及时做出反应,用于代替图项的信号,

    • 其中 value 值根据状态change确定,状态参数cange的取值是QGraphicsItem.GraphicsItemChange的枚举值,可取值如表所示。

    • 需要注意的是要使itemChange()函数能处理几何位置改变的通知,需要首先通过 setFlag()方法给图项设置QGraphicsItem,ItemSendsGeometryChanges标志,另外也不能在itemChange()函数中直接改变几何位置,否则会陷入死循环。

      QGraphIcsItem.GraphIcsltemChange的取值说明
      QGraphIcsItem.ItemEnabledChange3图项的激活状态(setEnable())即将改变时发送通 知。ItemChange()函数中的参数 value是新状态,value=True 时表明图项处于激活状态,value= False时表明图项处于失效状态。原激活状态可 用IsEnabled()方法获得
      QGraphIcsItem.ItemEnabledHasChanged13图项的激活状态已经改变时发送通知,ItemChange()函数中的参数 value 是新状态
      QGraphIcsItem.ItemPosItIonChange0图项的位置(setPos()、moveBy())即将改变时发 送通知,参数 value是相对于父图项改变后的位置 QPoIntF,原位置可以用pos()获得
      QGraphIcsItem.ItemPosItIonHasChanged9图项的位置已经改变时发送通知,参数value是相 对于父图项改变后的位置QPoIntF,与pos()方法 获取的位置相同
      QGraphIcsltem.ItemTransformChange8图项的变换矩阵(setTransform())即将改变时发 送通知,参数 value 是变换后的矩阵 QTransform,原变换矩阵可以用transform()方法获得
      QGraphIcsltem.ItemTransformHasChanged10图项的变换矩阵已经改变时发送通知,参数value 是变换后的矩阵QTransform,与transform()方法 获得的矩阵相同
      QGraphIcsltem.ItemRotatIonChange28图项即将产生旋转(setRotatIon())时发送通知,参 数 valIe是新的旋转角度,原旋转角可用rotatIon()方法获得
      QGraphIcsltem.ltemRotatIonHasChanged29图项已经严生旋转时发送通知,参数 value 是新的 旋转角度,与rotatIon()方法获得的旋转角相同
      QGraphIcslterm.ItemScaleChange .30图项即将进行缩放(setScale())时发送通知,参数 value是新的缩放系数,原缩放系数可用scale()方 法获得
      QGraphIcsItem.ItemScaleHasChanged31图项已经进行了缩放时发送通知,参数 value 是新 的缩放系数
      QGraphIcsItem.ItemTransformrIgInPoIntChange32图项变换原点(setTransformOrIgInPoInt())即将 改变时发送通知,参数 value 是新的点 QPoIntF。 原变换原点可用transformOrIgInPoInt()方法获得
      QGraphIcsItem.ItemTransformOrIgInPoIntHnsChanged33图项变换原点已经改变时发送通知,参数 value是 新的点 QPoIntF,原变换原点可用transformOrIgInPoInt()方法获得
      QGraphIcsItem.ItemSelectedChange4图项选中状态即将改变(setSelected())时发送通 知,参数value是选中后的状态(True或False),原 选中状态可用IsSelected()方法获得
      QGraphIcsltem.ItemSelectedHasChanged14图项的选中状态已经改变时发送通知,参数value 是选中后的状态
      QGraphIesItem.ItemVIsIbleChange2图项的可见性(setVIsIble())即将改变时发送通 知,参数value是新状态,原可见性状态可用IsVIsIble()方法获得
      QGraphIcsltem.ItenVIsIbleHasChanged12图项的可见性已经改变时发送通知,参数value是 新状态
      QGraphIcsltem.ItemParentChange5图项的父图项(setParentItem())即将改变时发送 通知,参数value是新的父图项QGraphIcsIten,原 父图项可用parentItem()方法获得
      QGraphIcsltem.ItemParentHasChanged15图项的父图项已经改变时发送通知,参数value是 新的父图项
      QGraphIcsltem.ItemChIldAddedChange6图项中即将添加子图项时发送通知,参数value是 新的子图项,予图项有可能还没完全构建
      QGraphIesItem.ItemChIldRemovedChange7图项中已经添加子图项时发送通知,鑫数value是 新的子图项
      QCIraphIcsltem.ItemSceneChange11图项即将加入到场景(addItem())中或即将从场 景中移除(removeltem())时发送通知、鑫数value 是新场景城None(移除时)原场景可用scene()方 法获得
      QGraphIcsItem.ItemSceneHasChanged16图项已经加人到场景中或即将从场景中移除时发 送通知,参数 value 是新场景或 None(移除时)
      QGraphIcsItem.ItemCursorChange17图项的光标形状(setCursor())即将改变时发送通 知,参数 value 是新光标QCursor,原光标可用cursor()方法获得
      QGraphIcsItem.ItemCursorHasChanged18图项的光标形状已经改变时发送通知,参数 value 是新光标 Qcursor
      QGraphIcsItem.Item ToolTIpChange19图项的提示信息(setToolTIp())即将改变时发送 通知,参数value是新提示信息,原提示信息可用toolTIp()方法获得:
      QGraphIcsItem.ItemToolTIpHasChanged20图项的提示信息已经改变时发送通知,参数 value 是新提示信息
      QGraphIcsItem.ItemFlagsChange21 .图项的标识(setFlags())即将改变时发送通知,参 数 value是新标识信息值
      QGraphIcsItem.ItemFlagsHaveChanged22图项的标识即将发生改变时发送通知,参数 value 是新标识信息值
      QGraphIcsItem.ItemZValueChange23图项的z值(setZValue())即将改变时发送通知,参数 value 是新的z值,原z值可用zValue()方法 获得
      QGraphIcsItem.ItemZValueHasChanged24图项的z值即将改变时发送通知,参数 value是新 的z值
      QGraphIcsItem.ItemOpacItyChange25图项的不透明度(setOpacIty())即将改变时发送 通知,参数value是新的不透明度,原不透明度可 用opacIty()方法获得
      QGraphIcsItem.ItemOpacItyHasChanged26图项的不透明度已经改变时发送通知,参数 value 是新的不透明度
      QGraphIcsItem.ItemScenePosItIonHasChanged27图项所在的场景的位置已经发生改变时发送通 知,参数 value 是新的场景位置,与 scenePos()方 法获得的位置相同
  • 用setCacheMode(mode: QGraphicsItem,CacheMode,cacheSize; QSize= Default(QSize))方法设置图项的缓冲模式,可以加快染速度。参数 mode 可取:

    • QGraphicsItem.NoCache时(默认值)没有缓冲每次都调用paint()方法重新绘制;
    • QGraphicsItem.ItemCoordinateCache,为图形项的逻辑(本地)坐标启用缓存,第一次绘制该图形项时,它将自身呈现到高速缓存中,然后对于以后的每次显示都重新使用该高速缓存;
    • QGraphicsItem.DeviceCoordinateCache,对绘图设备的坐标启用缓存,此模式适用于可以移动但不能旋转缩放或剪切的图项
  • 场景中有多个图项时,根据图项的z值确定哪个图项先绘制,值越大会越先绘制先绘制的图项会放到后绘制的图项的后面。

    • 用setZValue(float)方法设置图项的z值,用zValue()方法获取z值。
    • 用场景的addItem()方法添加图项时图项的初始值都是0.0,这时图项依照添加顺序来显示。
    • 如果一个图项有多个子项,则会先显示父图项,再显示子图项。可以用stackBefore(QGraphicsItem)方法将图项放到指定图项的前面
  • 用setPos(x,y)、setX(x)和 setY(y)方法设置图项在父图项中的位置。

    • pos()方法返回图项在父图项中的坐标位置,如果图项的父图项是场景,则返回其在场景中的坐标位置。
    • 除 pos()外的其他函数,返回的坐标值都是在图项自己的局部坐标系中的值。
  • 用setVisible(bool)方法可以显示或隐藏图项

    • 也可以用show()或 hide()方法显示或隐藏图项,
    • 如果图项有子图项,隐藏图项后,其子图项也隐藏。
  • 用setEnable(bool)方法可以设置图项是否激活,激活的图项可以接受键盘和鼠标事件,如果图项失效,其子项也会失效。

  • 用setData(key:int,value: Any)方法可以给图项设置一个任意类型的数据,

    • 用data(key:int)方法获取图项的数据
  • 碰撞检测需要重写 shape()函数来返回图项的精准轮廓,

    • 可以使用默认的collidesWithItem(QGraphicsItem,mode=Qt.IntersectsItemShape)值定义外形,
    • 如果图项的轮廓很复杂碰撞检测会消耗较长时间。
    • 也可重写 collidesWithItem()函数,提供一个新的图项和轮廓碰撞方法。
  • 用setPanelModality(QGraphicsItemPanelModality)方法设置图项的面板模式,

    • 图项是面板时会阻止对其他面板的输人,但不阻止对子图项的输人,参数QGraphicsItem,PanelModality 可以取:
      • QGraphicsItem,NonModal(默认值,不阻止对其他面板的输人)
      • QGraphicsItemPanelModal(阻止对父辈面板的输人)
      • QGraphicsItem.SceneModal(阻止对场景中所有面板的输入)
  • 用mapFromItem()方法或mapRectFromItem()方法可以从其他图项映射坐标

    • 用mapToItem()方法或 mapRectToItem()方法可以把坐标映射到其他图项坐标系中,
    • 用mapFromParent()方法或mapRectFromParent()方法可以映射父图项的坐标,
    • 用mapToParent()方法或 mapRectToParent()方法可以把图项坐标映射到父图项坐标系中,
    • 用mapFromScene()方法或 mapRectFromScene()方法可以从场景中映射坐标,
    • 用mapToScene()方法或 mapRectToScene()方法可以把坐标映射到场景坐标系中。
  • 图项的事件有:

    • contextMenuEvent()
    • focusInEvent()
    • focusOutEvent()
    • hoverEnterEvent()
    • hoverMoveEvent()
    • hoverLeaveEvent()
    • inputMethodEvent()
    • keyPressEvent()
    • keyReleaseEvent()
    • mousePressEvent()
    • mouseMoveEvent()
    • mouseReleaseEvent()
    • mouseDoubleClickEvent()
    • dragEnterEvent()
    • dragLeaveEvent()
    • dragMoyeEvent()
    • dropEvent()
    • wheelEvent()
    • sceneEvent(QEvent)
    • 用installSceneEventFilter(QGraphicsItem)方法给事件添加过滤器
    • 用sceneEventFilter(QGraphicsItem,QEvent)方法处理事件,并返回 bool型数据;
    • 用removeSceneEventFilter(QGraphicsItem)方法移除事件过滤器。
  • 可以通过 QGraphicsItemsetAcceptDrops()方法设置图项是否支持拖拽功能,还需要重写QGraphicsItem 的以下函数:

    • dragEnterEvent()
    • dragMoveEvent()
    • dropEvent()
    • dragLeaveEvent()
  • 创建继承自QGraphicsItem 的图项,图项可以设置自已的定时器,在 timerEvent()事件中控制图项的运动。通过调用QGraphicsScene,advance()函数来推进场景,再调用QGraphicsItemadvance()函数进行动画播放。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

士别三日,当挖目相待

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

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

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

打赏作者

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

抵扣说明:

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

余额充值