图项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.ItemEnabledChange 3 图项的激活状态(setEnable())即将改变时发送通 知。ItemChange()函数中的参数 value是新状态,value=True 时表明图项处于激活状态,value= False时表明图项处于失效状态。原激活状态可 用IsEnabled()方法获得 QGraphIcsItem.ItemEnabledHasChanged 13 图项的激活状态已经改变时发送通知,ItemChange()函数中的参数 value 是新状态 QGraphIcsItem.ItemPosItIonChange 0 图项的位置(setPos()、moveBy())即将改变时发 送通知,参数 value是相对于父图项改变后的位置 QPoIntF,原位置可以用pos()获得 QGraphIcsItem.ItemPosItIonHasChanged 9 图项的位置已经改变时发送通知,参数value是相 对于父图项改变后的位置QPoIntF,与pos()方法 获取的位置相同 QGraphIcsltem.ItemTransformChange 8 图项的变换矩阵(setTransform())即将改变时发 送通知,参数 value 是变换后的矩阵 QTransform,原变换矩阵可以用transform()方法获得 QGraphIcsltem.ItemTransformHasChanged 10 图项的变换矩阵已经改变时发送通知,参数value 是变换后的矩阵QTransform,与transform()方法 获得的矩阵相同 QGraphIcsltem.ItemRotatIonChange 28 图项即将产生旋转(setRotatIon())时发送通知,参 数 valIe是新的旋转角度,原旋转角可用rotatIon()方法获得 QGraphIcsltem.ltemRotatIonHasChanged 29 图项已经严生旋转时发送通知,参数 value 是新的 旋转角度,与rotatIon()方法获得的旋转角相同 QGraphIcslterm.ItemScaleChange . 30 图项即将进行缩放(setScale())时发送通知,参数 value是新的缩放系数,原缩放系数可用scale()方 法获得 QGraphIcsItem.ItemScaleHasChanged 31 图项已经进行了缩放时发送通知,参数 value 是新 的缩放系数 QGraphIcsItem.ItemTransformrIgInPoIntChange 32 图项变换原点(setTransformOrIgInPoInt())即将 改变时发送通知,参数 value 是新的点 QPoIntF。 原变换原点可用transformOrIgInPoInt()方法获得 QGraphIcsItem.ItemTransformOrIgInPoIntHnsChanged 33 图项变换原点已经改变时发送通知,参数 value是 新的点 QPoIntF,原变换原点可用transformOrIgInPoInt()方法获得 QGraphIcsItem.ItemSelectedChange 4 图项选中状态即将改变(setSelected())时发送通 知,参数value是选中后的状态(True或False),原 选中状态可用IsSelected()方法获得 QGraphIcsltem.ItemSelectedHasChanged 14 图项的选中状态已经改变时发送通知,参数value 是选中后的状态 QGraphIesItem.ItemVIsIbleChange 2 图项的可见性(setVIsIble())即将改变时发送通 知,参数value是新状态,原可见性状态可用IsVIsIble()方法获得 QGraphIcsltem.ItenVIsIbleHasChanged 12 图项的可见性已经改变时发送通知,参数value是 新状态 QGraphIcsltem.ItemParentChange 5 图项的父图项(setParentItem())即将改变时发送 通知,参数value是新的父图项QGraphIcsIten,原 父图项可用parentItem()方法获得 QGraphIcsltem.ItemParentHasChanged 15 图项的父图项已经改变时发送通知,参数value是 新的父图项 QGraphIcsltem.ItemChIldAddedChange 6 图项中即将添加子图项时发送通知,参数value是 新的子图项,予图项有可能还没完全构建 QGraphIesItem.ItemChIldRemovedChange 7 图项中已经添加子图项时发送通知,鑫数value是 新的子图项 QCIraphIcsltem.ItemSceneChange 11 图项即将加入到场景(addItem())中或即将从场 景中移除(removeltem())时发送通知、鑫数value 是新场景城None(移除时)原场景可用scene()方 法获得 QGraphIcsItem.ItemSceneHasChanged 16 图项已经加人到场景中或即将从场景中移除时发 送通知,参数 value 是新场景或 None(移除时) QGraphIcsItem.ItemCursorChange 17 图项的光标形状(setCursor())即将改变时发送通 知,参数 value 是新光标QCursor,原光标可用cursor()方法获得 QGraphIcsItem.ItemCursorHasChanged 18 图项的光标形状已经改变时发送通知,参数 value 是新光标 Qcursor QGraphIcsItem.Item ToolTIpChange 19 图项的提示信息(setToolTIp())即将改变时发送 通知,参数value是新提示信息,原提示信息可用toolTIp()方法获得: QGraphIcsItem.ItemToolTIpHasChanged 20 图项的提示信息已经改变时发送通知,参数 value 是新提示信息 QGraphIcsItem.ItemFlagsChange 21 . 图项的标识(setFlags())即将改变时发送通知,参 数 value是新标识信息值 QGraphIcsItem.ItemFlagsHaveChanged 22 图项的标识即将发生改变时发送通知,参数 value 是新标识信息值 QGraphIcsItem.ItemZValueChange 23 图项的z值(setZValue())即将改变时发送通知,参数 value 是新的z值,原z值可用zValue()方法 获得 QGraphIcsItem.ItemZValueHasChanged 24 图项的z值即将改变时发送通知,参数 value是新 的z值 QGraphIcsItem.ItemOpacItyChange 25 图项的不透明度(setOpacIty())即将改变时发送 通知,参数value是新的不透明度,原不透明度可 用opacIty()方法获得 QGraphIcsItem.ItemOpacItyHasChanged 26 图项的不透明度已经改变时发送通知,参数 value 是新的不透明度 QGraphIcsItem.ItemScenePosItIonHasChanged 27 图项所在的场景的位置已经发生改变时发送通 知,参数 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(阻止对场景中所有面板的输入)
- 图项是面板时会阻止对其他面板的输人,但不阻止对子图项的输人,参数QGraphicsItem,PanelModality 可以取:
-
用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()函数进行动画播放。