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

Blaine Bell blaine.bell at schrodinger.com
Thu Jun 3 15:19:11 BST 2010

Hi Phil,

Thanks a lot for your quick response.  Unfortunately, I am using 
sip-4.9.3, and neither of these fixes you have listed below work for me. 
(sipType_ChmMainWindow or %ModuleCode is not recognized).

Also, looking into the <module>cmodule.cpp file, sipType does not get 
instantiated in the static function that converts to a sub-class if 
possible.  Am I doing something wrong, or is it a version issue?



Phil Thompson wrote:
> 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,
> so...
>      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.
> Phil

More information about the PyQt mailing list