Search code examples
c++python-2.7pyqt4swig

SWIG Interface for calling Qt from Python


I try to call a C++ function from Python but I get:

TypeError: in method 'drawColorWheel_NoPerf', argument 2 of type 'QPainter *'

I use swig2.0.

The Python script: SmallExample.py

#!/usr/bin/env python

import sys
from PyQt4 import QtCore, QtGui
import Qt4SWIGSimple

class MB_Window (QtGui.QWidget):
    def __init__ (self, parent = None):
        super (self.__class__, self).__init__ (parent)

    def paintEvent (self, event):
        painter = QtGui.QPainter (self)

        LabelPos = QtCore.QPointF (100, 100)
        painter.drawText (LabelPos, "%s" % ("Hello, world!"))

        Radius = 2
        Qt4SWIGSimple.drawColorWheel_NoPerf (Radius, painter)
        # Traceback (most recent call last):
        #  File "./SmallExample.py", line 19, in paintEvent
        #  DrawColorWheel_NoPerf.drawColorWheel_NoPerf (Radius, painter)
        # TypeError: in method 'drawColorWheel_NoPerf', argument 2 of type 'QPainter *'

def main (theArgs):
    App = QtGui.QApplication (theArgs)
    theMainWindow = MB_Window ()
    theMainWindow.show ()

    App.exec_ ()

if __name__ == "__main__":
    main (sys.argv)

My interface till now:

Qt4SWIGSimple.i:

%include "typemaps.i"

%module Qt4SWIGSimple

%{
/*
void drawColorWheel_NoPerf (int radius, QPainter *painter);
*/
#include "Qt4SWIGSimple.h"
%}

/* Let's just grab the original header file here */
%include "Qt4SWIGSimple.h"

Qt4SWIGSimple.h:

//#ifndef MAINWINDOW_H
#include <QPainter>
//#endif // MAINWINDOW_H

#ifdef __cplusplus
extern "C" {
#endif

void drawColorWheel_NoPerf (int radius, QPainter *painter);

#ifdef __cplusplus
}
#endif

Many thanks for any help!


Solution

  • Thanks to https://stackoverflow.com/users/2001654/musicamante

    and another question

    passing pyqt object to swig exported c++ code

    I found a working solution. But I'm not quite satisfied as I think it should be easier.

    I changed the python-script to:

    ...
        import sip 
        PainterAddress = sip.unwrapinstance (painter)
        DrawColorWheel_NoPerf.drawColorWheel_NoPerf_Sip (Radius, PainterAddress)
    ...
    

    the header Qt4SWIGSimple.h: to:

    ...
    void drawColorWheel_NoPerf (int radius, QPainter *painter);
    void drawColorWheel_NoPerf_Sip (int radius, long _painter_address);
    ...
    

    and added into the c++ file:

    ...
    void drawColorWheel_NoPerf_Sip (int radius, long _painter_address) {
        drawColorWheel_NoPerf (radius, reinterpret_cast<QPainter*> (_painter_address));
    }
    ...