diff --git a/src/qpython.cpp b/src/qpython.cpp index 7e99c18..e5c97ce 100644 --- a/src/qpython.cpp +++ b/src/qpython.cpp @@ -298,15 +298,10 @@ QPython::evaluate(QString expr) return convertPyObjectToQVariant(o.borrow()); } -void -QPython::call(QVariant func, QVariant args, QJSValue callback) +QVariantList +QPython::unboxArgList(QVariant &args) { - QJSValue *cb = 0; - if (!callback.isNull() && !callback.isUndefined() && callback.isCallable()) { - cb = new QJSValue(callback); - } - // Unbox QJSValue from QVariant, since QJSValue::toVariant() can cause calls into - // QML engine and we don't want that to happen from non-GUI thread + // Unbox QJSValue from QVariant QVariantList vl = args.toList(); for (int i = 0, c = vl.count(); i < c; ++i) { QVariant &v = vl[i]; @@ -315,11 +310,31 @@ QPython::call(QVariant func, QVariant args, QJSValue callback) v = v.value().toVariant(); } } - emit process(func, vl, cb); + return vl; +} + +void +QPython::call(QVariant func, QVariant boxed_args, QJSValue callback) +{ + QJSValue *cb = 0; + if (!callback.isNull() && !callback.isUndefined() && callback.isCallable()) { + cb = new QJSValue(callback); + } + // Unbox QJSValue from QVariant, since QJSValue::toVariant() can cause calls into + // QML engine and we don't want that to happen from non-GUI thread + QVariantList unboxed_args = unboxArgList(boxed_args); + + emit process(func, unboxed_args, cb); } QVariant -QPython::call_sync(QVariant func, QVariant args) +QPython::call_sync(QVariant func, QVariant boxed_args) +{ + return call_internal(func, boxed_args, true); +} + +QVariant +QPython::call_internal(QVariant func, QVariant args, bool unbox) { ENSURE_GIL_STATE; @@ -348,8 +363,18 @@ QPython::call_sync(QVariant func, QVariant args) return QVariant(); } + // Unbox QJSValue from QVariant if requested. QPython::call may have done + // this already, but call_sync is also exposed directly, so it does not + // happen in this case otherwise + QVariant args_unboxed; + if (unbox) { + args_unboxed = unboxArgList(args); + } else { + args_unboxed = args; + } + QVariant v; - QString errorMessage = priv->call(callable.borrow(), name, args, &v); + QString errorMessage = priv->call(callable.borrow(), name, args_unboxed, &v); if (!errorMessage.isNull()) { emitError(errorMessage); } diff --git a/src/qpython.h b/src/qpython.h index 46e751f..5d8ad8c 100644 --- a/src/qpython.h +++ b/src/qpython.h @@ -297,7 +297,11 @@ class QPython : public QObject { * \result The return value of the Python call as Qt data type **/ Q_INVOKABLE QVariant - call_sync(QVariant func, QVariant args=QVariantList()); + call_sync(QVariant func, QVariant boxed_args=QVariantList()); + + QVariant + call_internal(QVariant func, QVariant boxed_args=QVariantList(), + bool unbox=true); /** * \brief Get an attribute value of a Python object synchronously @@ -361,7 +365,7 @@ class QPython : public QObject { void error(QString traceback); /* For internal use only */ - void process(QVariant func, QVariant args, QJSValue *callback); + void process(QVariant func, QVariant unboxed_args, QJSValue *callback); void import(QString name, QJSValue *callback); void import_names(QString name, QVariant args, QJSValue *callback); @@ -375,6 +379,8 @@ class QPython : public QObject { void disconnectNotify(const QMetaMethod &signal); private: + QVariantList unboxArgList(QVariant &args); + static QPythonPriv *priv; QPythonWorker *worker; diff --git a/src/qpython_worker.cpp b/src/qpython_worker.cpp index dbb4e50..abbf454 100644 --- a/src/qpython_worker.cpp +++ b/src/qpython_worker.cpp @@ -32,9 +32,9 @@ QPythonWorker::~QPythonWorker() } void -QPythonWorker::process(QVariant func, QVariant args, QJSValue *callback) +QPythonWorker::process(QVariant func, QVariant unboxed_args, QJSValue *callback) { - QVariant result = qpython->call_sync(func, args); + QVariant result = qpython->call_internal(func, unboxed_args, false); if (callback) { emit finished(result, callback); } diff --git a/src/qpython_worker.h b/src/qpython_worker.h index 2bacb2d..d540c1a 100644 --- a/src/qpython_worker.h +++ b/src/qpython_worker.h @@ -34,7 +34,7 @@ class QPythonWorker : public QObject { ~QPythonWorker(); public slots: - void process(QVariant func, QVariant args, QJSValue *callback); + void process(QVariant func, QVariant unboxed_args, QJSValue *callback); void import(QString func, QJSValue *callback); void import_names(QString func, QVariant args, QJSValue *callback);