[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