From 1b77fc5931bf14b2a9e936a8d08334d9e00ffe7e Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Tue, 8 Jan 2019 17:15:24 +0100 Subject: Add support for parameterNames in Signals There were many uses cases when a proper interaction between Python and Qml was needed, one of them was the case to emit signals from Python an get those values via an argument name in QML. A simple example describing this situation can be found in PYSIDE-634: Python: sumResult = Signal(int, arguments=["sum"]) sumResult.emit(42) Qml: onSumResult: console.log(sum) // will print 42 A test case based on the same example was added. Change-Id: I0908f97d88eaadc0c02d81bc4daca936f72f6c6a Fixes: PYSIDE-634 Reviewed-by: Christian Tismer --- sources/pyside2/libpyside/dynamicqmetaobject.cpp | 13 +++++++++++-- sources/pyside2/libpyside/pysidesignal.cpp | 23 +++++++++++++++++++++-- sources/pyside2/libpyside/pysidesignal_p.h | 3 ++- 3 files changed, 34 insertions(+), 5 deletions(-) (limited to 'sources/pyside2/libpyside') diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp index c5de54aa0..857d242a2 100644 --- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp +++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp @@ -467,8 +467,17 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) data->data->signalName = Shiboken::String::toCString(key); for (const auto &s : data->data->signatures) { const auto sig = data->data->signalName + '(' + s.signature + ')'; - if (m_baseObject->indexOfSignal(sig) == -1) - m_builder->addSignal(sig); + if (m_baseObject->indexOfSignal(sig) == -1) { + // Registering the parameterNames to the QMetaObject (PYSIDE-634) + // from: + // Signal(..., arguments=['...', ...] + // the arguments are now on data-data->signalArguments + if (!data->data->signalArguments->isEmpty()) { + m_builder->addSignal(sig).setParameterNames(*data->data->signalArguments); + } else { + m_builder->addSignal(sig); + } + } } } } diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp index 169028f0c..47a5fff43 100644 --- a/sources/pyside2/libpyside/pysidesignal.cpp +++ b/sources/pyside2/libpyside/pysidesignal.cpp @@ -203,14 +203,15 @@ PyTypeObject *PySideSignalInstanceTypeF(void) int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) { static PyObject *emptyTuple = nullptr; - static const char *kwlist[] = {"name", nullptr}; + static const char *kwlist[] = {"name", "arguments", nullptr}; char *argName = nullptr; + PyObject *argArguments = nullptr; if (emptyTuple == 0) emptyTuple = PyTuple_New(0); if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds, - "|s:QtCore." SIGNAL_CLASS_NAME, const_cast(kwlist), &argName)) + "|sO:QtCore." SIGNAL_CLASS_NAME, const_cast(kwlist), &argName, &argArguments)) return 0; bool tupledArgs = false; @@ -220,6 +221,24 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) if (argName) data->data->signalName = argName; + data->data->signalArguments = new QByteArrayList(); + if (argArguments && PySequence_Check(argArguments)) { + Py_ssize_t argument_size = PySequence_Size(argArguments); + for (Py_ssize_t i = 0; i < argument_size; ++i) { + PyObject *item = PySequence_GetItem(argArguments, i); +#ifdef IS_PY3K + PyObject *strObj = PyUnicode_AsUTF8String(item); + char *s = PyBytes_AsString(strObj); + Py_DECREF(strObj); +#else + char *s = PyBytes_AsString(item); +#endif + Py_DECREF(item); + if (s != nullptr) + data->data->signalArguments->append(QByteArray(s)); + } + } + for (Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) { PyObject *arg = PyTuple_GET_ITEM(args, i); if (PySequence_Check(arg) && !Shiboken::String::check(arg)) { diff --git a/sources/pyside2/libpyside/pysidesignal_p.h b/sources/pyside2/libpyside/pysidesignal_p.h index a5cd67f66..8027f4459 100644 --- a/sources/pyside2/libpyside/pysidesignal_p.h +++ b/sources/pyside2/libpyside/pysidesignal_p.h @@ -55,6 +55,7 @@ struct PySideSignalData QByteArray signalName; QVector signatures; + QByteArrayList *signalArguments; }; extern "C" @@ -64,7 +65,7 @@ extern "C" struct PySideSignal { PyObject_HEAD PySideSignalData *data; - PyObject* homonymousMethod; + PyObject *homonymousMethod; }; struct PySideSignalInstance; -- cgit v1.2.3