We have a nice Dynamic MetaObject! Yay!
Python signals and slots are like C++ signals and slots to Qt :-)
This commit is contained in:
parent
e791f15afc
commit
9e1a1ec8a7
9 changed files with 275 additions and 32 deletions
|
|
@ -1,12 +1,13 @@
|
||||||
project(libpyside)
|
project(libpyside)
|
||||||
|
|
||||||
set(libpyside_SRC
|
set(libpyside_SRC
|
||||||
typeresolver.cpp
|
|
||||||
proxyslot.cpp
|
|
||||||
abstractqobjectconnection.cpp
|
abstractqobjectconnection.cpp
|
||||||
|
dynamicqmetaobject.cpp
|
||||||
|
proxyslot.cpp
|
||||||
signalmanager.cpp
|
signalmanager.cpp
|
||||||
signalsignalconnection.cpp
|
signalsignalconnection.cpp
|
||||||
signalslotconnection.cpp
|
signalslotconnection.cpp
|
||||||
|
typeresolver.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "abstractqobjectconnection.h"
|
#include "abstractqobjectconnection.h"
|
||||||
#include "typeresolver.h"
|
#include "typeresolver.h"
|
||||||
#include "signalmanager.h"
|
#include "signalmanager.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace PySide;
|
using namespace PySide;
|
||||||
|
|
||||||
|
|
@ -50,7 +51,7 @@ void AbstractQObjectConnection::trigger(void** args)
|
||||||
int numArgs = m_signalArgs.count();
|
int numArgs = m_signalArgs.count();
|
||||||
PyObject* pyArgs = PyTuple_New(numArgs);
|
PyObject* pyArgs = PyTuple_New(numArgs);
|
||||||
for (int i = 0; i < numArgs; ++i) {
|
for (int i = 0; i < numArgs; ++i) {
|
||||||
PyObject* arg = TypeResolver::get(m_signalArgs[i])->toPython(args[i+1]);
|
PyObject* arg = TypeResolver::get(m_signalArgs[i])->toPython(args[i]);
|
||||||
PyTuple_SET_ITEM(pyArgs, i, arg);
|
PyTuple_SET_ITEM(pyArgs, i, arg);
|
||||||
}
|
}
|
||||||
trigger(pyArgs);
|
trigger(pyArgs);
|
||||||
|
|
|
||||||
155
libpyside/dynamicqmetaobject.cpp
Normal file
155
libpyside/dynamicqmetaobject.cpp
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Shiboken Python Bindings Generator project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
*
|
||||||
|
* Contact: PySide team <contact@pyside.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* version 2.1 as published by the Free Software Foundation. Please
|
||||||
|
* review the following information to ensure the GNU Lesser General
|
||||||
|
* Public License version 2.1 requirements will be met:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
*
|
||||||
|
* As a special exception to the GNU Lesser General Public License
|
||||||
|
* version 2.1, the object code form of a "work that uses the Library"
|
||||||
|
* may incorporate material from a header file that is part of the
|
||||||
|
* Library. You may distribute such object code under terms of your
|
||||||
|
* choice, provided that the incorporated material (i) does not exceed
|
||||||
|
* more than 5% of the total size of the Library; and (ii) is limited to
|
||||||
|
* numerical parameters, data structure layouts, accessors, macros,
|
||||||
|
* inline functions and templates.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dynamicqmetaobject.h"
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace PySide;
|
||||||
|
|
||||||
|
static int registerString(const QByteArray& s, QList<QByteArray>* strings)
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
for (int i = 0; i < strings->count(); ++i) {
|
||||||
|
const QString &str = strings->at(i);
|
||||||
|
if (str == s)
|
||||||
|
return idx;
|
||||||
|
idx += str.length() + 1;
|
||||||
|
}
|
||||||
|
strings->append(s);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicQMetaObject::DynamicQMetaObject(const QObject* object) : m_originalMetaObject(object->metaObject())
|
||||||
|
{
|
||||||
|
m_metaObject.d.superdata = m_originalMetaObject;
|
||||||
|
m_metaObject.d.stringdata = 0;
|
||||||
|
m_metaObject.d.data = 0;
|
||||||
|
m_metaObject.d.extradata = 0;
|
||||||
|
m_stringData = 0;
|
||||||
|
m_data = 0;
|
||||||
|
updateMetaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicQMetaObject::~DynamicQMetaObject()
|
||||||
|
{
|
||||||
|
delete[] m_stringData;
|
||||||
|
delete[] m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicQMetaObject::addSignal(const char* signal)
|
||||||
|
{
|
||||||
|
m_signals << QByteArray(signal);
|
||||||
|
updateMetaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicQMetaObject::addSlot(const char* slot)
|
||||||
|
{
|
||||||
|
m_signals << QByteArray(slot);
|
||||||
|
updateMetaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicQMetaObject::updateMetaObject()
|
||||||
|
{
|
||||||
|
// these values are from moc source code, generator.cpp:66
|
||||||
|
enum MethodFlags {
|
||||||
|
AccessPrivate = 0x00,
|
||||||
|
AccessProtected = 0x01,
|
||||||
|
AccessPublic = 0x02,
|
||||||
|
MethodMethod = 0x00,
|
||||||
|
MethodSignal = 0x04,
|
||||||
|
MethodSlot = 0x08,
|
||||||
|
MethodConstructor = 0x0c,
|
||||||
|
MethodCompatibility = 0x10,
|
||||||
|
MethodCloned = 0x20,
|
||||||
|
MethodScriptable = 0x40
|
||||||
|
};
|
||||||
|
|
||||||
|
uint n_signals = m_signals.count();
|
||||||
|
uint n_methods = n_signals + m_slots.count();
|
||||||
|
int header[] = {2, // revision
|
||||||
|
0, // class name index in m_metadata
|
||||||
|
0, 0, // classinfo and classinfo index, not used by us
|
||||||
|
n_methods, 0, // method count and method list index
|
||||||
|
0, 0, // prop count and prop indexes
|
||||||
|
0, 0 // enum count and enum index
|
||||||
|
};
|
||||||
|
|
||||||
|
const int HEADER_LENGHT = sizeof(header)/sizeof(int);
|
||||||
|
header[5] = HEADER_LENGHT;
|
||||||
|
// header size + 5 indexes per method + an ending zero
|
||||||
|
delete[] m_data;
|
||||||
|
m_data = new uint[HEADER_LENGHT + n_methods*5 + 1];
|
||||||
|
std::memcpy(m_data, header, sizeof(header));
|
||||||
|
|
||||||
|
QList<QByteArray> strings;
|
||||||
|
registerString(m_originalMetaObject->className(), &strings); // register class string
|
||||||
|
const int NULL_INDEX = registerString("", &strings); // register a null string
|
||||||
|
int index = HEADER_LENGHT;
|
||||||
|
|
||||||
|
//write signals
|
||||||
|
foreach(QByteArray signal, m_signals) {
|
||||||
|
m_data[index++] = registerString(signal, &strings); // func name
|
||||||
|
m_data[index++] = NULL_INDEX; // arguments
|
||||||
|
m_data[index++] = NULL_INDEX; // normalized type
|
||||||
|
m_data[index++] = NULL_INDEX; // tags
|
||||||
|
m_data[index++] = AccessPublic | MethodSignal; // flags
|
||||||
|
}
|
||||||
|
//write slots
|
||||||
|
foreach(QByteArray slot, m_slots) {
|
||||||
|
m_data[index++] = registerString(slot, &strings); // func name
|
||||||
|
m_data[index++] = NULL_INDEX; // arguments
|
||||||
|
m_data[index++] = NULL_INDEX; // normalized type
|
||||||
|
m_data[index++] = NULL_INDEX; // tags
|
||||||
|
m_data[index++] = AccessPublic | MethodSlot; // flags
|
||||||
|
}
|
||||||
|
m_data[index++] = 0; // the end
|
||||||
|
|
||||||
|
// create the m_metadata string
|
||||||
|
QByteArray str;
|
||||||
|
foreach(QByteArray signature, strings) {
|
||||||
|
str.append(signature);
|
||||||
|
str.append(char(0));
|
||||||
|
}
|
||||||
|
delete[] m_stringData;
|
||||||
|
m_stringData = new char[str.count()];
|
||||||
|
std::copy(str.begin(), str.end(), m_stringData);
|
||||||
|
|
||||||
|
// create metaobject
|
||||||
|
m_metaObject.d.stringdata = m_stringData;
|
||||||
|
m_metaObject.d.data = m_data;
|
||||||
|
}
|
||||||
72
libpyside/dynamicqmetaobject.h
Normal file
72
libpyside/dynamicqmetaobject.h
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Shiboken Python Bindings Generator project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
*
|
||||||
|
* Contact: PySide team <contact@pyside.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* version 2.1 as published by the Free Software Foundation. Please
|
||||||
|
* review the following information to ensure the GNU Lesser General
|
||||||
|
* Public License version 2.1 requirements will be met:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
*
|
||||||
|
* As a special exception to the GNU Lesser General Public License
|
||||||
|
* version 2.1, the object code form of a "work that uses the Library"
|
||||||
|
* may incorporate material from a header file that is part of the
|
||||||
|
* Library. You may distribute such object code under terms of your
|
||||||
|
* choice, provided that the incorporated material (i) does not exceed
|
||||||
|
* more than 5% of the total size of the Library; and (ii) is limited to
|
||||||
|
* numerical parameters, data structure layouts, accessors, macros,
|
||||||
|
* inline functions and templates.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DYNAMICQMETAOBJECT_H
|
||||||
|
#define DYNAMICQMETAOBJECT_H
|
||||||
|
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QLinkedList>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
class QObject;
|
||||||
|
|
||||||
|
namespace PySide
|
||||||
|
{
|
||||||
|
|
||||||
|
class DynamicQMetaObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DynamicQMetaObject(const QObject* object);
|
||||||
|
~DynamicQMetaObject();
|
||||||
|
void addSignal(const char* signal);
|
||||||
|
void addSlot(const char* slot);
|
||||||
|
|
||||||
|
const QMetaObject* metaObject() const
|
||||||
|
{
|
||||||
|
return &m_metaObject;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const QMetaObject* m_originalMetaObject;
|
||||||
|
QMetaObject m_metaObject;
|
||||||
|
|
||||||
|
QLinkedList<QByteArray> m_signals;
|
||||||
|
QLinkedList<QByteArray> m_slots;
|
||||||
|
unsigned int* m_data;
|
||||||
|
char* m_stringData;
|
||||||
|
|
||||||
|
void updateMetaObject();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
using namespace PySide;
|
using namespace PySide;
|
||||||
|
|
||||||
ProxySlot::ProxySlot(QObject* signalSource) : m_signalSource(signalSource)
|
ProxySlot::ProxySlot(const QObject* signalSource) : m_metaObject(signalSource), m_signalSource(signalSource)
|
||||||
{
|
{
|
||||||
m_nextSlotIndex = m_signalSource->metaObject()->methodCount()-1;
|
m_nextSlotIndex = m_signalSource->metaObject()->methodCount()-1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include "dynamicqmetaobject.h"
|
||||||
|
|
||||||
namespace PySide
|
namespace PySide
|
||||||
{
|
{
|
||||||
|
|
@ -43,8 +44,13 @@ class AbstractQObjectConnection;
|
||||||
class ProxySlot : public QObject
|
class ProxySlot : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProxySlot(QObject* signalSource);
|
ProxySlot(const QObject* signalSource);
|
||||||
bool connect(AbstractQObjectConnection* connection);
|
bool connect(AbstractQObjectConnection* connection);
|
||||||
|
DynamicQMetaObject* dynamicQMetaObject()
|
||||||
|
{
|
||||||
|
return &m_metaObject;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Qt's meta-object system uses the qt_metacall() function to access the
|
* Qt's meta-object system uses the qt_metacall() function to access the
|
||||||
|
|
@ -69,7 +75,8 @@ protected:
|
||||||
int qt_metacall(QMetaObject::Call call, int id, void **args);
|
int qt_metacall(QMetaObject::Call call, int id, void **args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QObject* m_signalSource;
|
DynamicQMetaObject m_metaObject;
|
||||||
|
const QObject* m_signalSource;
|
||||||
int m_nextSlotIndex;
|
int m_nextSlotIndex;
|
||||||
// slot_index => connection_info, used by qt_metacall
|
// slot_index => connection_info, used by qt_metacall
|
||||||
// to recover the connection_info
|
// to recover the connection_info
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,16 @@ QStringList PySide::getArgsFromSignature(const char* signature)
|
||||||
|
|
||||||
struct SignalManager::SignalManagerPrivate
|
struct SignalManager::SignalManagerPrivate
|
||||||
{
|
{
|
||||||
QHash<QObject*, ProxySlot*> m_proxies;
|
QHash<const QObject*, ProxySlot*> m_proxies;
|
||||||
|
|
||||||
ProxySlot* findProxy(QObject* signalSource)
|
ProxySlot* findProxy(const QObject* signalSource) const
|
||||||
{
|
{
|
||||||
ProxySlot* proxy = m_proxies.value(signalSource);
|
return m_proxies.value(signalSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxySlot* getProxy(const QObject* signalSource)
|
||||||
|
{
|
||||||
|
ProxySlot* proxy = findProxy(signalSource);
|
||||||
if (!proxy) {
|
if (!proxy) {
|
||||||
proxy = new ProxySlot(signalSource);
|
proxy = new ProxySlot(signalSource);
|
||||||
m_proxies[signalSource] = proxy;
|
m_proxies[signalSource] = proxy;
|
||||||
|
|
@ -110,7 +115,9 @@ bool SignalManager::connect(QObject* source, const char* signal, PyObject* callb
|
||||||
return false;
|
return false;
|
||||||
signal++;
|
signal++;
|
||||||
|
|
||||||
ProxySlot* proxy = m_d->findProxy(source);
|
ProxySlot* proxy = m_d->getProxy(source);
|
||||||
|
if (source->metaObject()->indexOfSignal(signal) == -1)
|
||||||
|
proxy->dynamicQMetaObject()->addSignal(signal);
|
||||||
AbstractQObjectConnection* connection = new SignalSlotConnection(source, signal, callback, type);
|
AbstractQObjectConnection* connection = new SignalSlotConnection(source, signal, callback, type);
|
||||||
return proxy->connect(connection);
|
return proxy->connect(connection);
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +139,7 @@ bool SignalManager::connect(QObject* source, const char* signal, QObject* receiv
|
||||||
receiver, slot_index, type);
|
receiver, slot_index, type);
|
||||||
} else {
|
} else {
|
||||||
// We have a python slot or signal
|
// We have a python slot or signal
|
||||||
ProxySlot* proxy = m_d->findProxy(source);
|
ProxySlot* proxy = m_d->getProxy(source);
|
||||||
AbstractQObjectConnection* connection = 0;
|
AbstractQObjectConnection* connection = 0;
|
||||||
retval = proxy->connect(connection);
|
retval = proxy->connect(connection);
|
||||||
}
|
}
|
||||||
|
|
@ -142,18 +149,14 @@ bool SignalManager::connect(QObject* source, const char* signal, QObject* receiv
|
||||||
|
|
||||||
bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* args)
|
bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* args)
|
||||||
{
|
{
|
||||||
if (checkSignal(signal))
|
if (!checkSignal(signal))
|
||||||
return false;
|
return false;
|
||||||
|
signal++;
|
||||||
|
|
||||||
int argsGiven = PySequence_Size(args);
|
int argsGiven = PySequence_Size(args);
|
||||||
|
|
||||||
//search native signal
|
int signalIndex = source->metaObject()->indexOfSignal(signal);
|
||||||
int signalIndex = source->metaObject()->indexOfSignal(signal+1);
|
if (signalIndex != -1) {
|
||||||
if (signalIndex == -1) {
|
|
||||||
// dynamic signal
|
|
||||||
qDebug() << "Dynamic signal not implemented yet!";
|
|
||||||
} else {
|
|
||||||
// a C++ signal
|
|
||||||
QStringList argTypes = getArgsFromSignature(signal);
|
QStringList argTypes = getArgsFromSignature(signal);
|
||||||
void* signalArgs[argsGiven+1];
|
void* signalArgs[argsGiven+1];
|
||||||
|
|
||||||
|
|
@ -166,7 +169,15 @@ bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* ar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PySide::SignalManager::removeProxySlot(QObject* signalSource)
|
void PySide::SignalManager::removeProxySlot(const QObject* signalSource)
|
||||||
{
|
{
|
||||||
m_d->m_proxies.remove(signalSource);
|
m_d->m_proxies.remove(signalSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QMetaObject* PySide::SignalManager::getMetaObject(const QObject* object) const
|
||||||
|
{
|
||||||
|
ProxySlot* proxy = m_d->findProxy(object);
|
||||||
|
if (proxy)
|
||||||
|
return proxy->dynamicQMetaObject()->metaObject();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ public:
|
||||||
bool connect(QObject* source, const char* signal, PyObject* callback, Qt::ConnectionType type = Qt::AutoConnection);
|
bool connect(QObject* source, const char* signal, PyObject* callback, Qt::ConnectionType type = Qt::AutoConnection);
|
||||||
bool connect(QObject* source, const char* signal, QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::AutoConnection);
|
bool connect(QObject* source, const char* signal, QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::AutoConnection);
|
||||||
bool emitSignal(QObject* source, const char* signal, PyObject* args);
|
bool emitSignal(QObject* source, const char* signal, PyObject* args);
|
||||||
void removeProxySlot(QObject* signalSource);
|
void removeProxySlot(const QObject* signalSource);
|
||||||
|
const QMetaObject* getMetaObject(const QObject* object) const;
|
||||||
private:
|
private:
|
||||||
struct SignalManagerPrivate;
|
struct SignalManagerPrivate;
|
||||||
SignalManagerPrivate* m_d;
|
SignalManagerPrivate* m_d;
|
||||||
|
|
|
||||||
|
|
@ -59,21 +59,15 @@ SignalSlotConnection::~SignalSlotConnection()
|
||||||
|
|
||||||
void SignalSlotConnection::trigger(PyObject* args)
|
void SignalSlotConnection::trigger(PyObject* args)
|
||||||
{
|
{
|
||||||
int useSelf = m_receiver ? 1 : 0;
|
Q_ASSERT(PySequence_Size(args) >= m_numSlotArgs);
|
||||||
int numArgs = PySequence_Size(args);
|
const int useSelf = m_receiver ? 1 : 0;
|
||||||
PyObject* preparedArgs = PyTuple_New(numArgs + useSelf);
|
|
||||||
|
PyObject* preparedArgs = PyTuple_New(m_numSlotArgs);
|
||||||
if (m_receiver)
|
if (m_receiver)
|
||||||
PyTuple_SetItem(preparedArgs, 0, m_receiver);
|
PyTuple_SetItem(preparedArgs, 0, m_receiver);
|
||||||
for (int i = 0; i < numArgs; ++i)
|
for (int i = 0; i < m_numSlotArgs; ++i)
|
||||||
PyTuple_SET_ITEM(preparedArgs, i + useSelf, PyTuple_GET_ITEM(args, i));
|
PyTuple_SET_ITEM(preparedArgs, i + useSelf, PyTuple_GET_ITEM(args, i));
|
||||||
|
|
||||||
qDebug() << "num args: " << m_numSlotArgs;
|
|
||||||
// sliceamento
|
|
||||||
// if (m_num_slot_args != -1 && m_num_slot_args < python::len(args)) {
|
|
||||||
// args = python::list(args.slice(0, m_num_slot_args));
|
|
||||||
// }
|
|
||||||
qDebug() << "Receiver" << m_receiver;
|
|
||||||
qDebug() << "numargs" << numArgs;
|
|
||||||
PyObject* retval = PyObject_CallObject(m_function, preparedArgs);
|
PyObject* retval = PyObject_CallObject(m_function, preparedArgs);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
Py_DECREF(retval);
|
Py_DECREF(retval);
|
||||||
|
|
@ -81,4 +75,5 @@ void SignalSlotConnection::trigger(PyObject* args)
|
||||||
qWarning(qPrintable(QString("Error calling slot ")+
|
qWarning(qPrintable(QString("Error calling slot ")+
|
||||||
PyString_AS_STRING(reinterpret_cast<PyCodeObject*>(PyFunction_GET_CODE(m_function))->co_name)));
|
PyString_AS_STRING(reinterpret_cast<PyCodeObject*>(PyFunction_GET_CODE(m_function))->co_name)));
|
||||||
}
|
}
|
||||||
|
Py_DECREF(preparedArgs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue