[PyQt] sip %ConvertToSubClassCode problem with %TypeHeaderCode doesn't work as expected.

Phil Thompson phil at riverbankcomputing.com
Thu Jun 3 10:14:36 BST 2010

On Wed, 02 Jun 2010 17:20:26 -0400, Blaine Bell
<blaine.bell at schrodinger.com> wrote:
> I am new to using SIP, and I find it *very* difficult to find reasonable 
> documentation and examples to do what I need to do.  I want to be able 
> to have SIP automatically cast my instances to a subclass.  I am using 
> "%ConvertToSubClassCode" that uses dynamic_cast<> to figure out whether 
> the sipCpp is my class, and if it is, then I convert it to the related 
> sip class.  Here is the snippet of my code:
> ~~~~~~~~~~~~~~~
> class ChmMainWindow : ChmBaseView
> {
> %TypeHeaderCode
> #include "chmmainwindow.h"
> %End
> %ConvertToSubClassCode
>     ChmMainWindow *mw = dynamic_cast<ChmMainWindow *>(sipCpp);
>     if (mw){
>         sipClass = sipAPI_canvasapp->api_find_class("ChmMainWindow");
>     } else {
>         sipClass = NULL;
>     }
> %End
> ~~~~~~~~~~~~~~~

A few problems with the above code...

sipClass is deprecated, use sipType instead.

There is no need to search for a type if you know its name at compile time,

     if (mw){
         sipType = sipType_ChmMainWindow;
     } else {
         sipType = NULL;

If you do want to use the C API then use the function names...

    sipType = sipFindType("ChmMainWindow");

> However, the compiler fails to recognize the "ChmMainWindow" class when 
> compiling the sipcanvasappcmodule.cpp file because the %TypeHeaderCode 
> does not get put into that file before this code. (i.e., this code only 
> gets put into the actual SIP wrapper cpp file).  My workaround is to put 
> this "#include "chmmainwindow.h" into a different %TypeHeaderCode block 
> further down the SIP file, and this seems to work fine (I am not sure 
> why some %TypeHeaderCode blocks get put into the cmodule and some others 
> do not).

%TypeHeaderCode is only placed in the sip*cmodule.cpp if sip thinks it is
needed. To explicitly add code to this file use the %ModuleCode directive.

> Also, I am not sure why (forgive my ignorance) this isn't the default 
> behavior?  Why shouldn't subclasses implemented in SIP get converted by 
> default?

Because there is no standard way to do the conversion. Unless you have
control over how the underlying library is built you can't guarantee that
compiler generated RTTI is available.

> I see the Qt code implements all of the casting in one object 
> (i.e., QApplication), is it a performance issue?

Putting all the code in one place (per module, per class hierarchy) does
generate less code and will be slightly faster, but it isn't required.


More information about the PyQt mailing list