类型发现

当从指向基类的指针转换属于类层次结构的对象时,期望获得实际的最派生类型的Python类型,这与C++不同,C++需要为此进行类型转换:

def event(self, event):
    if event.type() == QEvent.Type.MousePress:
        self.do_things(event.position())
...
bool event(QEvent *event) override
{
    if (event->type() == QEvent::MousePress) {
        auto *mouseEvent = static_cast<QMouseEvent *>(event);
        doThings(mouseEvent->position());
    ...
}

确定事件类型的过程称为类型发现

Shiboken 生成代码以自动检测类型。首先,它尝试为通过 typeid(*pointer).name() 获得的名称找到一个转换器。这通常应该有效,因为该名称由绑定注册。如果失败,它开始遍历在 libshiboken 中构建的类型继承图,通过使用转换函数(默认情况下为 dynamic_cast<>)来检查并找到最派生的类。

对于具有虚析构函数的普通类层次结构,通常不需要特殊处理,因为typeid()通常会检测到正确的类名。

多重继承

在C++的多重继承情况下,如果不是单行直接继承,则不会进行到派生类的转换。例如,在Qt中,类QWidget同时继承了QObjectQObject层次结构的基类)和QPaintDevice

当调用一个返回QPaintDevice *的函数时,例如 QPainter.device(),返回的是一个表示QPaintDevice的Python类型, 而不是底层的小部件类型。这个限制存在是因为 C++中的底层指针是一个指向QPaintDevice *的指针,并且与 指向QWidget的指针不同。

具有非虚析构函数的类层次结构

有一些具有层次结构的C++类没有虚析构函数。这使得基于typeid()dynamic_cast<>的类型发现变得不可能。

Qt中的示例是QStyleOption派生的或QGradient派生的类。

对于这些类,需要在类型条目上指定一些属性:

首先,必须指定一个polymorphic-id-expression属性,用作替换dynamic_cast<>的检查。

此外,可以指定一个polymorphic-name-function属性。 这取代了通过typeid()获得的类型名称猜测,主要是为了通过跳过继承图中每种类型的检查来加快速度。

一个polymorphic-base属性标识了层次结构的基类。在基类继承自另一个类的情况下,应提供此属性以防止逻辑深入到基类以下。

使用类型发现属性为具有虚拟析构函数的类层次结构

可以使用polymorphic-id-expressionpolymorphic-name-function来处理具有虚析构函数的普通类层次结构,因为它们基本上取代了typeid()dynamic_cast<>。如果能够指定比虚表检查更快的表达式,这样做是有意义的。

指定polymorphic-base在多重继承的情况下生成特殊的转换函数也是有意义的。例如,在Qt中,QWindowQLayoutQWidget是层次结构的基类。由于它们都继承自QObject,指定基类可以防止逻辑使用QObject作为基类。

类型发现属性参考

以下与类型发现相关的属性可以在 object-typevalue-type 元素上指定:

多态ID表达式

polymorphic-id-expression 属性指定了一个表达式,用于检查基类指针是否匹配特定类型。例如,在 virtual eventHandler(BaseEvent *e) 函数中,此属性用于构建与派生类(例如 MouseEvent 或类似类)匹配的 Python 包装器。属性值可能包含占位符:

%1

完全限定的类名

%B

基类的完全限定名称(通过基类搜索找到或由polymorphic-base指示)。

要检查继承BaseEvent的类,请指定:

<object-type name="MouseEvent"
             polymorphic-id-expression="%B-&gt;type() == BaseEvent::MouseEvent"/>

多态名称函数

polymorphic-name-function 属性指定了一个函数的名称,该函数在基类类型条目上返回派生类的类型名称。通常,typeid(ptr).name() 用于此目的。

该函数预计返回 const char *

多态基础

布尔属性 polymorphic-base 表示该类是否为类层次结构的基类。它用于 polymorphic-id-expression 中的 %B 占位符以及多重继承中的类型转换操作。