[PyQt] [SIP] SIP_PYCALLABLE in constructor
    Sandro Mani 
    manisandro at gmail.com
       
    Thu Oct 31 09:22:42 GMT 2019
    
    
  
Hi
I'm trying to create bindings for a class Foo with a constructor taking 
a std::function, so basically for
     typedef std::function<Item*()> ItemFactory;
     Foo( ItemFactory factory, QObject* parent = 0 );
in the sip file I'm writing
     Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
     %MethodCode
     // Make sure the callable doesn't get garbage collected, this is 
needed because refcount for a1 is 0
     // and the creation function pointer is passed to the metadata and 
it needs to be kept in memory.
     Py_INCREF( a0 );
     Py_BEGIN_ALLOW_THREADS
     auto factory = [a0]() -> Item *
     {
       Item *result = nullptr;
       SIP_BLOCK_THREADS
       PyObject *s = sipCallMethod( NULL, a0, NULL );
       int state;
       int sipIsError = 0;
       result = reinterpret_cast<Item *>( sipConvertToType( s, 
sipType_Item, NULL, SIP_NO_CONVERTORS, &state, &sipIsError ) );
       SIP_UNBLOCK_THREADS
       return result;
     };
     sipCpp = new sipFoo( factory, a1 );
     Py_END_ALLOW_THREADS
     %End
This however does not work, due to
error: no matching function for call to ‘Foo::Foo(PyObject*&, QObject*&)’
Any pointers how to do this? Full example code below.
Many thanks
Sandro
-------------- foo.h --------------
#ifndef FOO_H
#define FOO_H
#include <functional>
#include <QObject>
#include <QVector>
class Item {
public:
     virtual ~Item() {}
};
class Foo : public QObject
{
     Q_OBJECT
   public:
     typedef std::function<Item*()> ItemFactory;
     Foo( ItemFactory factory, QObject* parent = 0 );
     ~Foo();
     void create();
   private:
     ItemFactory mFactory;
     QVector<Item *> mItems;
};
#endif // FOO_H
-------------- foo.cpp --------------
#include "foo.h"
Foo::Foo( ItemFactory factory, QObject *parent )
   : QObject( parent ), mFactory(factory)
{
}
Foo::~Foo()
{
   qDeleteAll( mItems );
}
void Foo::create()
{
     mItems.append(mFactory());
}
-------------- foo.sip --------------
%Module(name=foo,
         keyword_arguments="All")
%Import QtCore/QtCoremod.sip
class Item
{
%TypeHeaderCode
#include "foo.h"
%End
     virtual ~Item();
};
class Foo : QObject
{
%TypeHeaderCode
#include "foo.h"
%End
   public:
     Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
     %MethodCode
     // Make sure the callable doesn't get garbage collected, this is 
needed because refcount for a1 is 0
     // and the creation function pointer is passed to the metadata and 
it needs to be kept in memory.
     Py_INCREF( a0 );
     Py_BEGIN_ALLOW_THREADS
     auto factory = [a0]() -> Item *
     {
       Item *result = nullptr;
       SIP_BLOCK_THREADS
       PyObject *s = sipCallMethod( NULL, a0, NULL );
       int state;
       int sipIsError = 0;
       result = reinterpret_cast<Item *>( sipConvertToType( s, 
sipType_Item, NULL, SIP_NO_CONVERTORS, &state, &sipIsError ) );
       SIP_UNBLOCK_THREADS
       return result;
     };
     sipCpp = new sipFoo( factory, a1 );
     Py_END_ALLOW_THREADS
     %End
     ~Foo();
};
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20191031/fa068d3c/attachment.html>
    
    
More information about the PyQt
mailing list