QGraphicsItem的类型检测与转换

简介: 简述由于 QGraphicsScene 和 QGraphicsItem 的大多数便利函数(例如:items(),selectedItems()、collidingItems()、childItems())返回一个 QList<QGraphicsItem *> 列表,在遍历列表的时候,通常需要对其中的 QGraphicsItem 进行类型检测与转换,以确定实

简述

由于 QGraphicsScene 和 QGraphicsItem 的大多数便利函数例如items()selectedItems()、collidingItems()、childItems()返回一个 QList<QGraphicsItem *> 列表在遍历列表的时候通常需要对其中的 QGraphicsItem 进行类型检测与转换以确定实际的 item。

类型检测

QGraphicsItem 中包含两个与类型相关的枚举值

enum {
    Type = 1,
    UserType = 65536
};

QGraphicsItem::Type

QGraphicsItem::Type 是标准 item 类中 virtual type() 函数返回的类型值。所有标准 item 与唯一的 Type 值相关联。例如QGraphicsPathItem::type() 返回的值为 2。

class QGraphicsPathItem : public QAbstractGraphicsShapeItem
{
public:
    enum { Type = 2 };
    int type() const { return Type; }
    ...
};

其他标准 item 类似Type 分别为 3、4、5……

QGraphicsItem::UserType

QGraphicsItem::UserType 是自定义 itemQGraphicsItem 或任何标准 item 的子类的最小允许类型值。该值与 QGraphicsItem::type() 的重新实现结合使用并声明一个 Type 枚举值。例如

class CustomItem : public QGraphicsItem
{
public:
    enum { Type = UserType + 1 };

    int type() const
    {
        // 针对该 item 启用 qgraphicsitem_cast
        return Type;
    }
    ...
};

注意要使 qgraphicsitem_cast 与自定义 item 一起正常工作需要为其重新实现 type() 函数。

类型转换

T qgraphicsitem_cast(QGraphicsItem *item)

如果 item 是类型 T返回指定 item 转换为类型 T否则返回 0。

template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
{
    typedef typename QtPrivate::remove_cv<typename QtPrivate::remove_pointer<T>::type>::type Item;
    return int(Item::Type) == int(QGraphicsItem::Type)
        || (item && int(Item::Type) == item->type()) ? static_cast<T>(item) : 0;
}

实际应用

下面以获取 QGraphicsScene 中的所有 items 为例

QList<QGraphicsItem *> items = scene->items();
foreach (QGraphicsItem *item, items) {
    if (item->type() == QGraphicsRectItem::Type) {  // 矩形
        QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem*>(item);
        // 访问 QGraphicsRectItem 的成员
    } else if (item->type() == QGraphicsLineItem::Type) {  // 直线
        QGraphicsLineItem *line = qgraphicsitem_cast<QGraphicsLineItem*>(item);
        // 访问 QGraphicsLineItem 的成员
    } else if (item->type() == QGraphicsProxyWidget::Type) {  // 代理 Widget
        QGraphicsProxyWidget *proxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget*>(item);
        QLabel *label = qobject_cast<QLabel *>(proxyWidget->widget());
        // 访问 QLabel 的成员
    } else if (item->type() == CustomItem::Type) {  // 自定义 Item
        CustomItem *customItem = qgraphicsitem_cast<CustomItem*>(item);
        // 访问 CustomItem 的成员
    } else {
        // 其他类型 item
    }
}

首先根据 type() 判断 item 的类型。然后通过 qgraphicsitem_cast 进行转换。这样既可以访问标准 item也可以通过 QGraphicsProxyWidget 访问 QWidget以及访问自定义 item。

目录
相关文章
|
JavaScript
vue element plus DatePicker 日期选择器
vue element plus DatePicker 日期选择器
783 0
《QT从基础到进阶·二十六》绘制多个图形项(QGraphicsRectItem,QGraphicsLineItem,QGraphicsPolygonItem)
《QT从基础到进阶·二十六》绘制多个图形项(QGraphicsRectItem,QGraphicsLineItem,QGraphicsPolygonItem)
483 0
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用
2452 1
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用
|
JSON 数据可视化 API
玩转数据科学:Python实战分析天气预报变动趋势
【10月更文挑战第1天】随着气候变化对日常生活的影响日益显著,理解和预测天气模式变得越来越重要。本文将引导您如何使用Python来抓取和分析天气预报数据,从而揭示天气变化的趋势。我们将介绍从获取公开气象API的数据到清洗、处理以及可视化整个过程的技术方法。
815 2
|
存储 数据可视化 测试技术
[Qt5] QGraphics图形视图框架概述(Item、Scene和View)
[Qt5] QGraphics图形视图框架概述(Item、Scene和View)
2541 0
|
开发框架 前端开发 JavaScript
在Winform界面使用自定义用户控件及TabelPanel和StackPanel布局控件
在Winform界面使用自定义用户控件及TabelPanel和StackPanel布局控件
|
机器学习/深度学习 人工智能 自然语言处理
|
存储 自然语言处理 算法
OpenIM Bot: 用LLM构建企业专属的智能客服
OpenIM Bot 通过结合LLM和RAG技术,构建企业专属的智能客服系统。该系统通过优化向量存储、混合检索和查询分析,解决了LLM的幻觉、新鲜度、token长度和数据安全问题,提升了用户体验。向量存储和预处理步骤确保文档高质量,而混合检索结合文本和语义搜索,增强了检索结果的准确性。通过迭代优化,OpenIM Bot 提供了高效、智能的支持服务,减轻了支持团队的负担,提升了问题解决效率。
1368 3
OpenIM Bot: 用LLM构建企业专属的智能客服
|
存储 安全 Java
全面探索Spring框架中的事件处理机制
在现代应用程序中,各个组件之间的通信是至关重要的。想象一下,你的应用程序中的各个模块像是一个巨大的交响乐团,每个模块都是一位音乐家,而Spring事件机制就像是指挥家,将所有音乐家协调得天衣无缝。这种松耦合的通信方式使你的应用程序更加灵活、可维护,而且能够轻松应对变化。现在,让我们进入这个令人兴奋的音乐厅,探索Spring事件的世界。