QGraphicsItem 自定义是否被选中

2024-06-19 14:04

本文主要是介绍QGraphicsItem 自定义是否被选中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、默认模式

在Qt中,你可以通过设置 QGraphicsItem 的标志位(flags)来自定义图形项是否可以被选中。默认情况下,QGraphicsItem 是可以被选中的,除非你显式地禁用了这个功能。

以下是如何设置 QGraphicsItem 使其可以被选中的代码示例:

QGraphicsItem *item = new QGraphicsItem();
item->setFlag(QGraphicsItem::ItemIsSelectable, true); // 使图形项可以被选中

如果你想确保图形项始终处于选中状态,你可以使用 setSelected() 方法:

item->setSelected(true); // 设置图形项为选中状态

请注意,即使设置了 ItemIsSelectable 标志位,用户仍然需要通过与图形项交互(例如点击)来实际选中它。如果你想要图形项在创建时就自动被选中,你应该调用 setSelected(true)

另外,如果你想在图形项被选中时执行某些操作,你可以重新实现 QGraphicsItemmousePressEvent() 或其他相关的事件处理函数,并在其中调用 setSelected() 方法。

class CustomGraphicsItem : public QGraphicsItem {
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override {QGraphicsItem::mousePressEvent(event);setSelected(true); // 当鼠标按下时,设置图形项为选中状态
}
};

在这个例子中,当用户点击 CustomGraphicsItem 时,它会自动被设置为选中状态。

二、自定义图像模式

在 Qt 的 QGraphicsItem 框架中,如果您想要自定义的图形项能够被选择和交互,需要满足两个条件。这是因为 QGraphicsItem 的选择和交互机制依赖于其形状(shape)和边界矩形(bounding rectangle)来确定鼠标事件是否与其相关。

  1. 重写 QPainterPath shape() const override 方法

这个方法应该返回一个 QPainterPath,它紧密地包围了您的自定义图形。这个路径用于精确的碰撞检测和事件处理。如果您的自定义图形比较复杂,生成这个路径可能会有点复杂,但这是确保精确选择和高效事件处理的关键。

QPainterPath MyGraphicsItem::shape() const {  QPainterPath path;  // 根据您的图形项形状构建路径  // 例如,如果您的图形是一个矩形:  path.addRect(QRectF(0, 0, 100, 100));  return path;  
}
  1. 重写 QRectF boundingRect() const override 方法

这个方法应该返回一个 QRectF,它是包围您图形项的最小矩形。这个矩形用于快速剔除不在其范围内的鼠标事件,从而提高性能。通常,这个矩形应该比 shape() 方法返回的 QPainterPath 要大,因为它是一个简单的矩形,而 shape() 可以是任意形状。

QRectF MyGraphicsItem::boundingRect() const {  // 返回一个包含您图形项所有部分的矩形  return QRectF(0, 0, 100, 100);  
}

通过正确实现这两个方法,您的自定义 QGraphicsItem 就可以像其他标准 QGraphicsItem 一样被选择和交互了。当鼠标事件发生时,QGraphicsView 会首先检查事件位置是否在项的 boundingRect 内。如果是,则会进一步检查事件位置是否在 shape 内,以确定是否触发事件。这样,即使您的图形项形状复杂,也能确保正确的交互行为。

这篇关于QGraphicsItem 自定义是否被选中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1075235

相关文章

JavaScript全屏,监听页面是否全屏

在JavaScript中,直接监听浏览器是否进入全屏模式并不直接支持,因为全屏API主要是关于请求和退出全屏模式的,而没有直接的监听器可以告知页面何时进入或退出全屏模式。但是,你可以通过在你的代码中跟踪全屏状态的改变来模拟这个功能。 以下是一个基本的示例,展示了如何使用全屏API来请求全屏模式,并在请求成功或失败时更新一个状态变量: javascriptlet isInFullscreen =

ROS话题通信流程自定义数据格式

ROS话题通信流程自定义数据格式 需求流程实现步骤定义msg文件编辑配置文件编译 在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如:

添加自定义的CALayer

iOS开发UI篇—CAlayer(创建图层) 一、添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控制器view的layer上)  1 // 2 // YYViewController.m 3 // 01-创建一个简单的图层 4 // 5 //

TableView 当前选中的行号。 默认会使哪一行选中 加入导航条后contentInset向下偏移的64

1.得到当前选中的行号     NSLog(@"%ld %s",  [self.tableView indexPathForSelectedRow].row,__func__); 2.默认选中表格的那一行     [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0 ]

android自定义View的和FramgentActivity的一个小坑

对于自定义View //加载样式TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBarView, defStyleAttr, 0);setTitle(typedArray.getString(R.styleable.TitleBarView_main_title));//不能写成

第三十七章 添加和使用自定义标题元素 - 自定义标头的继承

文章目录 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承自定义标头的继承示例 在 `SOAPHEADERS` 参数中指定支持的标头元素自定义标头的继承 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承 自定义标头的继承 如果创建此Web 服务的子类,该子类将继承不特定于方法的标头信息 — 包含在 <request> 或 <response> 元素中的标头信

算法7— 判断一个单链表是否有环,如果有,找出环的起始位置

第一种方法是从单链表head开始,每遍历一个,就把那个node放在hashset里,走到下一个的时候,把该node放在hashset里查找,如果有相同的,就表示有环,如果走到单链表最后一个node,在hashset里都没有重复的node,就表示没有环。 这种方法需要O(n)的空间和时间。 第二种方法是设置两个指针指向单链表的head, 然后开始遍历,第一个指针走一步,第二个指针走两步,如果没

算法6— 判断两个链表是否相交

问题: 给出两个单向链表的头指针,比如h1、h2,判断链表是否相交,如果不相交返回NULL;如果相交,返回指向第一个相交节点的指针。时间复杂度控制在O(n)。 分析: 如果两单向链表相交的话,一定是Y型相交,不可能出现X型,弄清楚这点后接下来的工作就是: (1)先找到h1,h2的最后一个节点L1和L2,同时记录节点数量a,b;(这里假设 a > b) (2)判断最后一个节点是否相同

自定义recyclerView实现时光轴效果

时光轴效果在很多app上都有出现,例如淘宝中快递的跟踪,本文将使用recyclerView实现时光轴效果,我们会到自定义控件,首先先看一下效果图: 接下来是步骤分析 1自定义属性 这个大家应该都了解了,根据我们之前的分析,直接在attrs.xml中进行声明 <declare-styleable name="TimeLine"><attr name="beginLine" f

Android自定义系列——9.Path详细用法

rXxx方法 rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标)。 Path path = new Path();path.moveTo(100,100);path.lineTo(100,200);canvas.drawPath(path,mDeafultPaint); 在这个例子中,先移动点到坐标(100,100)处,之后再连接