diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-09-27 08:39:02 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-09-27 08:23:31 +0000 |
commit | c9dc377e79f93c078b622f61814a4c264a948852 (patch) | |
tree | ffc13d0c8cc15fa3b25291facf38e6d8828d0a07 /sources/pyside2/libpyside/signalmanager.cpp.in | |
parent | 2412e332a9984891aa481176141d403183ac3b11 (diff) |
libpyside: Replace configuration of signalmanager.cpp by defines
This makes the development process easier.
Task-number: PYSIDE-784
Change-Id: I07ced4b25b65c90e5a17d85be9b8f15a26e5d07d
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'sources/pyside2/libpyside/signalmanager.cpp.in')
-rw-r--r-- | sources/pyside2/libpyside/signalmanager.cpp.in | 702 |
1 files changed, 0 insertions, 702 deletions
diff --git a/sources/pyside2/libpyside/signalmanager.cpp.in b/sources/pyside2/libpyside/signalmanager.cpp.in deleted file mode 100644 index 9b5c5eb9a..000000000 --- a/sources/pyside2/libpyside/signalmanager.cpp.in +++ /dev/null @@ -1,702 +0,0 @@ -// -*- mode: cpp;-*- -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "signalmanager.h" -#include "pysidesignal.h" -#include "pysideproperty.h" -#include "pysideproperty_p.h" -#include "pyside.h" -#include "dynamicqmetaobject.h" -#include "pysidemetafunction_p.h" - -#include <QtCore> -#include <QHash> -#include <QStringList> -#include <QMetaMethod> -#include <autodecref.h> -#include <gilstate.h> -#include <QDebug> -#include <limits> -#include <algorithm> -#include <basewrapper.h> -#include <bindingmanager.h> -#include <sbkconverter.h> -#include <sbkstring.h> - -// These private headers are needed to throw JavaScript exceptions -#if @QML_PRIVATE_API_SUPPORT@ - #include <private/qv4engine_p.h> - #include <private/qv4context_p.h> - #include <private/qqmldata_p.h> -#if QT_VERSION < 0x050700 - #include <private/qqmlcontextwrapper_p.h> -#endif -#endif - -#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2 -#error QSLOT_CODE and/or QSIGNAL_CODE changed! change the hardcoded stuff to the correct value! -#endif -#define PYSIDE_SLOT '1' -#define PYSIDE_SIGNAL '2' -#include "globalreceiverv2.h" -#include "globalreceiver.h" - -#define PYTHON_TYPE "PyObject" - -namespace { - static PyObject *metaObjectAttr = 0; - - static int callMethod(QObject* object, int id, void** args); - static PyObject* parseArguments(const QList< QByteArray >& paramTypes, void** args); - static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args); - -#ifdef IS_PY3K - static void destroyMetaObject(PyObject* obj) - { - void* ptr = PyCapsule_GetPointer(obj, 0); - PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(ptr); - SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta); - if (wrapper) - Shiboken::BindingManager::instance().releaseWrapper(wrapper); - delete meta; - } - -#else - static void destroyMetaObject(void* obj) - { - PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(obj); - SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta); - if (wrapper) - Shiboken::BindingManager::instance().releaseWrapper(wrapper); - delete meta; - } -#endif -} - -namespace PySide { - - -PyObjectWrapper::PyObjectWrapper() - :m_me(Py_None) -{ - Py_XINCREF(m_me); -} - -PyObjectWrapper::PyObjectWrapper(PyObject* me) - : m_me(me) -{ - Py_XINCREF(m_me); -} - -PyObjectWrapper::PyObjectWrapper(const PyObjectWrapper &other) - : m_me(other.m_me) -{ - Py_XINCREF(m_me); -} - -PyObjectWrapper::~PyObjectWrapper() -{ - // Check that Python is still initialized as sometimes this is called by a static destructor - // after Python interpeter is shutdown. - if (!Py_IsInitialized()) - return; - - Shiboken::GilState gil; - Py_XDECREF(m_me); -} - -void PyObjectWrapper::reset(PyObject *o) -{ - Py_XINCREF(o); - Py_XDECREF(m_me); - m_me = o; -} - -PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other) -{ - reset(other.m_me); - return *this; -} - -PyObjectWrapper::operator PyObject*() const -{ - return m_me; -} - -QDataStream &operator<<(QDataStream& out, const PyObjectWrapper& myObj) -{ - if (Py_IsInitialized() == 0) { - qWarning() << "Stream operator for PyObject called without python interpreter."; - return out; - } - - static PyObject *reduce_func = 0; - - Shiboken::GilState gil; - if (!reduce_func) { - Shiboken::AutoDecRef pickleModule(PyImport_ImportModule("pickle")); - reduce_func = PyObject_GetAttrString(pickleModule, "dumps"); - } - Shiboken::AutoDecRef repr(PyObject_CallFunctionObjArgs(reduce_func, (PyObject*)myObj, NULL)); - if (repr.object()) { - const char* buff = 0; - Py_ssize_t size = 0; - if (PyBytes_Check(repr.object())) { - buff = PyBytes_AS_STRING(repr.object()); - size = PyBytes_GET_SIZE(repr.object()); - } else if (Shiboken::String::check(repr.object())) { - buff = Shiboken::String::toCString(repr.object()); - size = Shiboken::String::len(repr.object()); - } - QByteArray data(buff, size); - out << data; - } - return out; -} - -QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj) -{ - if (Py_IsInitialized() == 0) { - qWarning() << "Stream operator for PyObject called without python interpreter."; - return in; - } - - static PyObject *eval_func = 0; - - Shiboken::GilState gil; - if (!eval_func) { - Shiboken::AutoDecRef pickleModule(PyImport_ImportModule("pickle")); - eval_func = PyObject_GetAttrString(pickleModule, "loads"); - } - - QByteArray repr; - in >> repr; - Shiboken::AutoDecRef pyCode(PyBytes_FromStringAndSize(repr.data(), repr.size())); - Shiboken::AutoDecRef value(PyObject_CallFunctionObjArgs(eval_func, pyCode.object(), 0)); - if (!value.object()) - value.reset(Py_None); - myObj.reset(value); - return in; -} - -}; - -using namespace PySide; - -struct SignalManager::SignalManagerPrivate -{ - SharedMap m_globalReceivers; - - //Deprecated - GlobalReceiver m_globalReceiver; - - SignalManagerPrivate() - { - m_globalReceivers = SharedMap( new QMap<QByteArray, GlobalReceiverV2*>() ); - } - - ~SignalManagerPrivate() - { - if (!m_globalReceivers.isNull()) { - // Delete receivers by always retrieving the current first element, because deleting a - // receiver can indirectly delete another one, and if we use qDeleteAll, that could - // cause either a double delete, or iterator invalidation, and thus undefined behavior. - while (!m_globalReceivers->isEmpty()) - delete *m_globalReceivers->cbegin(); - Q_ASSERT(m_globalReceivers->isEmpty()); - } - } -}; - -static void clearSignalManager() -{ - PySide::SignalManager::instance().clear(); -} - -static void PyObject_PythonToCpp_PyObject_PTR(PyObject* pyIn, void* cppOut) -{ - *((PyObject**)cppOut) = pyIn; -} -static PythonToCppFunc is_PyObject_PythonToCpp_PyObject_PTR_Convertible(PyObject* pyIn) -{ - return PyObject_PythonToCpp_PyObject_PTR; -} -static PyObject* PyObject_PTR_CppToPython_PyObject(const void* cppIn) -{ - PyObject* pyOut = (PyObject*)cppIn; - if (pyOut) - Py_INCREF(pyOut); - return pyOut; -} - -SignalManager::SignalManager() : m_d(new SignalManagerPrivate) -{ - // Register Qt primitive typedefs used on signals. - using namespace Shiboken; - - // Register PyObject type to use in queued signal and slot connections - qRegisterMetaType<PyObjectWrapper>(PYTHON_TYPE); - qRegisterMetaTypeStreamOperators<PyObjectWrapper>(PYTHON_TYPE); - qRegisterMetaTypeStreamOperators<PyObjectWrapper>("PyObjectWrapper"); - qRegisterMetaTypeStreamOperators<PyObjectWrapper>("PySide::PyObjectWrapper"); - - SbkConverter* converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, 0); - Shiboken::Conversions::setCppPointerToPythonFunction(converter, PyObject_PTR_CppToPython_PyObject); - Shiboken::Conversions::setPythonToCppPointerFunctions(converter, PyObject_PythonToCpp_PyObject_PTR, is_PyObject_PythonToCpp_PyObject_PTR_Convertible); - Shiboken::Conversions::registerConverterName(converter, PYTHON_TYPE); - Shiboken::Conversions::registerConverterName(converter, "object"); - Shiboken::Conversions::registerConverterName(converter, "PyObjectWrapper"); - Shiboken::Conversions::registerConverterName(converter, "PySide::PyObjectWrapper"); - - PySide::registerCleanupFunction(clearSignalManager); - - if (!metaObjectAttr) - metaObjectAttr = Shiboken::String::fromCString("__METAOBJECT__"); -} - -void SignalManager::clear() -{ - delete m_d; - m_d = new SignalManagerPrivate(); -} - -SignalManager::~SignalManager() -{ - delete m_d; -} - -SignalManager& SignalManager::instance() -{ - static SignalManager me; - return me; -} - -QObject* SignalManager::globalReceiver() -{ - return &m_d->m_globalReceiver; -} - -void SignalManager::globalReceiverConnectNotify(QObject* source, int slotIndex) -{ - m_d->m_globalReceiver.connectNotify(source, slotIndex); -} - -void SignalManager::globalReceiverDisconnectNotify(QObject* source, int slotIndex) -{ - m_d->m_globalReceiver.disconnectNotify(source, slotIndex); -} - -void SignalManager::addGlobalSlot(const char* slot, PyObject* callback) -{ - m_d->m_globalReceiver.addSlot(slot, callback); -} - -int SignalManager::addGlobalSlotGetIndex(const char* slot, PyObject* callback) -{ - return m_d->m_globalReceiver.addSlot(slot, callback); -} - -QObject* SignalManager::globalReceiver(QObject *sender, PyObject *callback) -{ - SharedMap globalReceivers = m_d->m_globalReceivers; - QByteArray hash = GlobalReceiverV2::hash(callback); - GlobalReceiverV2* gr = 0; - auto it = globalReceivers->find(hash); - if (it == globalReceivers->end()) { - gr = new GlobalReceiverV2(callback, globalReceivers); - globalReceivers->insert(hash, gr); - if (sender) { - gr->incRef(sender); // create a link reference - gr->decRef(); // remove extra reference - } - } else { - gr = it.value(); - if (sender) - gr->incRef(sender); - } - - return reinterpret_cast<QObject*>(gr); -} - -int SignalManager::countConnectionsWith(const QObject *object) -{ - int count = 0; - for (GlobalReceiverV2Map::const_iterator it = m_d->m_globalReceivers->cbegin(), end = m_d->m_globalReceivers->cend(); it != end; ++it) { - if (it.value()->refCount(object)) - count++; - } - return count; -} - -void SignalManager::notifyGlobalReceiver(QObject* receiver) -{ - reinterpret_cast<GlobalReceiverV2*>(receiver)->notify(); -} - -void SignalManager::releaseGlobalReceiver(const QObject* source, QObject* receiver) -{ - GlobalReceiverV2* gr = reinterpret_cast<GlobalReceiverV2*>(receiver); - gr->decRef(source); -} - -int SignalManager::globalReceiverSlotIndex(QObject* receiver, const char* signature) const -{ - return reinterpret_cast<GlobalReceiverV2*>(receiver)->addSlot(signature); -} - -bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* args) -{ - if (!Signal::checkQtSignal(signal)) - return false; - signal++; - - int signalIndex = source->metaObject()->indexOfSignal(signal); - if (signalIndex != -1) { - // cryptic but works! - // if the signature doesn't have a '(' it's a shor circuited signal, i.e. std::find - // returned the string null terminator. - bool isShortCircuit = !*std::find(signal, signal + std::strlen(signal), '('); - if (isShortCircuit) - return emitShortCircuitSignal(source, signalIndex, args); - else - return MetaFunction::call(source, signalIndex, args); - } - return false; -} - -int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id, void** args) -{ - const QMetaObject* metaObject = object->metaObject(); - PySideProperty* pp = 0; - PyObject* pp_name = 0; - QMetaProperty mp; - PyObject* pySelf = 0; - int methodCount = metaObject->methodCount(); - int propertyCount = metaObject->propertyCount(); - - if (call != QMetaObject::InvokeMetaMethod) { - mp = metaObject->property(id); - if (!mp.isValid()) { - return id - methodCount; - } - - Shiboken::GilState gil; - pySelf = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object); - Q_ASSERT(pySelf); - pp_name = Shiboken::String::fromCString(mp.name()); - pp = Property::getObject(pySelf, pp_name); - if (!pp) { - qWarning("Invalid property: %s.", mp.name()); - Py_XDECREF(pp_name); - return id - methodCount; - } - } - - switch(call) { -#ifndef QT_NO_PROPERTIES - case QMetaObject::ReadProperty: - case QMetaObject::WriteProperty: - case QMetaObject::ResetProperty: - case QMetaObject::QueryPropertyDesignable: - case QMetaObject::QueryPropertyScriptable: - case QMetaObject::QueryPropertyStored: - case QMetaObject::QueryPropertyEditable: - case QMetaObject::QueryPropertyUser: - pp->d->metaCallHandler(pp, pySelf, call, args); - break; -#endif - case QMetaObject::InvokeMetaMethod: - id = callMethod(object, id, args); - break; - - default: - qWarning("Unsupported meta invocation type."); - } - - // WARNING Isn't safe to call any metaObject and/or object methods beyond this point - // because the object can be deleted inside the called slot. - - if (call == QMetaObject::InvokeMetaMethod) { - id = id - methodCount; - } else { - id = id - propertyCount; - } - - if (pp || pp_name) { - Shiboken::GilState gil; - Py_XDECREF(pp); - Py_XDECREF(pp_name); - } - - // Bubbles Python exceptions up to the Javascript engine, if called from one - { - Shiboken::GilState gil; - - if (PyErr_Occurred()) { - -#if @QML_PRIVATE_API_SUPPORT@ - // This JS engine grabber based off of Qt 5.5's `qjsEngine` function - QQmlData *data = QQmlData::get(object, false); - - if (data && !data->jsWrapper.isNullOrUndefined()) { - QV4::ExecutionEngine *engine = data->jsWrapper.engine(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) - if (engine->currentStackFrame != nullptr) { -#elif QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - if (engine->currentContext->d() != engine->rootContext()->d()) { -#else - QV4::ExecutionContext *ctx = engine->currentContext(); - if (ctx->type == QV4::Heap::ExecutionContext::Type_CallContext || - ctx->type == QV4::Heap::ExecutionContext::Type_SimpleCallContext) { -#endif - PyObject *errType, *errValue, *errTraceback; - PyErr_Fetch(&errType, &errValue, &errTraceback); - // PYSIDE-464: The error is only valid before PyErr_Restore, - // PYSIDE-464: therefore we take local copies. - Shiboken::AutoDecRef objStr(PyObject_Str(errValue)); - const QString errString = QLatin1String(Shiboken::String::toCString(objStr)); - const bool isSyntaxError = errType == PyExc_SyntaxError; - const bool isTypeError = errType == PyExc_TypeError; - PyErr_Restore(errType, errValue, errTraceback); - - PyErr_Print(); // Note: PyErr_Print clears the error. - -#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) - if (isSyntaxError) { - return engine->throwSyntaxError(errString); - } else if (isTypeError) { - return engine->throwTypeError(errString); - } else { - return engine->throwError(errString); - } -#else - if (isSyntaxError) { - return ctx->throwSyntaxError(errString); - } else if (isTypeError) { - return ctx->throwTypeError(errString); - } else { - return ctx->throwError(errString); - } -#endif - } - } -#endif - - int reclimit = Py_GetRecursionLimit(); - // Inspired by Python's errors.c: PyErr_GivenExceptionMatches() function. - // Temporarily bump the recursion limit, so that PyErr_Print will not raise a recursion - // error again. Don't do it when the limit is already insanely high, to avoid overflow. - if (reclimit < (1 << 30)) - Py_SetRecursionLimit(reclimit + 5); - PyErr_Print(); - Py_SetRecursionLimit(reclimit); - } - } - - return id; -} - -int SignalManager::callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* pyMethod, bool isShortCuit) -{ - Q_ASSERT(pyMethod); - - Shiboken::GilState gil; - PyObject* pyArguments = 0; - - if (isShortCuit){ - pyArguments = reinterpret_cast<PyObject*>(args[1]); - } else { - pyArguments = parseArguments(method.parameterTypes(), args); - } - - if (pyArguments) { - Shiboken::Conversions::SpecificConverter* retConverter = NULL; - const char* returnType = method.typeName(); - if (returnType && std::strcmp("", returnType) && std::strcmp("void", returnType)) { - retConverter = new Shiboken::Conversions::SpecificConverter(returnType); - if (!retConverter || !*retConverter) { - PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s' to call Python meta method.", returnType); - return -1; - } - } - - Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments)); - - if (!isShortCuit && pyArguments){ - Py_DECREF(pyArguments); - } - - if (!retval.isNull() && retval != Py_None && !PyErr_Occurred() && retConverter) { - retConverter->toCpp(retval, args[0]); - } - delete retConverter; - } - - return -1; -} - -bool SignalManager::registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type) -{ - int ret = registerMetaMethodGetIndex(source, signature, type); - return (ret != -1); -} - -int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type) -{ - if (!source) { - qWarning("SignalManager::registerMetaMethodGetIndex(\"%s\") called with source=nullptr.", - signature); - return -1; - } - const QMetaObject* metaObject = source->metaObject(); - int methodIndex = metaObject->indexOfMethod(signature); - // Create the dynamic signal is needed - if (methodIndex == -1) { - SbkObject* self = Shiboken::BindingManager::instance().retrieveWrapper(source); - if (!Shiboken::Object::hasCppWrapper(self)) { - qWarning() << "Invalid Signal signature:" << signature; - return -1; - } else { - DynamicQMetaObject *dmo = 0; - PyObject *pySelf = reinterpret_cast<PyObject*>(self); - PyObject* dict = self->ob_dict; - - // Create a instance meta object - if (!dict || !PyDict_Contains(dict, metaObjectAttr)) { - dmo = new DynamicQMetaObject(Py_TYPE(pySelf), metaObject); -#ifdef IS_PY3K - PyObject* pyDmo = PyCapsule_New(dmo, 0, destroyMetaObject); -#else - PyObject* pyDmo = PyCObject_FromVoidPtr(dmo, destroyMetaObject); -#endif - - PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo); - Py_DECREF(pyDmo); - } else { - dmo = reinterpret_cast<DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject)); - } - - if (type == QMetaMethod::Signal) - return dmo->addSignal(signature); - else - return dmo->addSlot(signature); - } - } - return methodIndex; -} - -bool SignalManager::hasConnectionWith(const QObject *object) -{ - return m_d->m_globalReceiver.hasConnectionWith(object); -} - -const QMetaObject* SignalManager::retrieveMetaObject(PyObject *self) -{ - Shiboken::GilState gil; - DynamicQMetaObject *mo = 0; - Q_ASSERT(self); - - PyObject* dict = reinterpret_cast<SbkObject*>(self)->ob_dict; - if (dict && PyDict_Contains(dict, metaObjectAttr)) { - PyObject *pyMo = PyDict_GetItem(dict, metaObjectAttr); - -#ifdef IS_PY3K - mo = reinterpret_cast<DynamicQMetaObject*>(PyCapsule_GetPointer(pyMo, 0)); -#else - mo = reinterpret_cast<DynamicQMetaObject*>(PyCObject_AsVoidPtr(pyMo)); -#endif - } else { - mo = reinterpret_cast<DynamicQMetaObject*>(Shiboken::Object::getTypeUserData(reinterpret_cast<SbkObject*>(self))); - } - - mo->update(); - return mo; -} - -namespace { - -static int callMethod(QObject* object, int id, void** args) -{ - const QMetaObject* metaObject = object->metaObject(); - QMetaMethod method = metaObject->method(id); - - if (method.methodType() == QMetaMethod::Signal) { - // emit python signal - QMetaObject::activate(object, id, args); - } else { - Shiboken::GilState gil; - PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object); - QByteArray methodName = method.methodSignature(); - methodName.truncate(methodName.indexOf('(')); - Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(self, methodName)); - return SignalManager::callPythonMetaMethod(method, args, pyMethod, false); - } - return -1; -} - - -static PyObject* parseArguments(const QList<QByteArray>& paramTypes, void** args) -{ - int argsSize = paramTypes.count(); - PyObject* preparedArgs = PyTuple_New(argsSize); - - for (int i = 0, max = argsSize; i < max; ++i) { - void* data = args[i+1]; - const char* dataType = paramTypes[i].constData(); - Shiboken::Conversions::SpecificConverter converter(dataType); - if (converter) { - PyTuple_SET_ITEM(preparedArgs, i, converter.toPython(data)); - } else { - PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); - Py_DECREF(preparedArgs); - return 0; - } - } - return preparedArgs; -} - -static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args) -{ - void* signalArgs[2] = {0, args}; - source->qt_metacall(QMetaObject::InvokeMetaMethod, signalIndex, signalArgs); - return true; -} - -} //namespace |