Skip to content

Commit 00f9a37

Browse files
committed
added support for kwargs on call() methods
1 parent f0aa966 commit 00f9a37

4 files changed

Lines changed: 53 additions & 29 deletions

File tree

src/PythonQt.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,21 +1007,21 @@ QStringList PythonQt::introspectType(const QString& typeName, ObjectType type)
10071007
return results;
10081008
}
10091009

1010-
QVariant PythonQt::call(PyObject* object, const QString& name, const QVariantList& args)
1010+
QVariant PythonQt::call(PyObject* object, const QString& name, const QVariantList& args, const QVariantMap& kwargs)
10111011
{
10121012
PythonQtObjectPtr callable = lookupCallable(object, name);
10131013
if (callable) {
1014-
return call(callable, args);
1014+
return call(callable, args, kwargs);
10151015
} else {
10161016
return QVariant();
10171017
}
10181018
}
10191019

1020-
QVariant PythonQt::call(PyObject* callable, const QVariantList& args)
1020+
QVariant PythonQt::call(PyObject* callable, const QVariantList& args, const QVariantMap& kwargs)
10211021
{
10221022
QVariant r;
10231023
PythonQtObjectPtr result;
1024-
result.setNewRef(callAndReturnPyObject(callable, args));
1024+
result.setNewRef(callAndReturnPyObject(callable, args, kwargs));
10251025
if (result) {
10261026
r = PythonQtConv::PyObjToQVariant(result);
10271027
} else {
@@ -1030,31 +1030,54 @@ QVariant PythonQt::call(PyObject* callable, const QVariantList& args)
10301030
return r;
10311031
}
10321032

1033-
PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList& args)
1033+
PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList& args, const QVariantMap& kwargs)
10341034
{
10351035
PyObject* result = NULL;
10361036
if (callable) {
1037+
bool err = false;
10371038
PythonQtObjectPtr pargs;
10381039
int count = args.size();
1039-
if (count>0) {
1040+
if ((count > 0) || (kwargs.count() > 0)) { // create empty tuple if kwargs are given
10401041
pargs.setNewRef(PyTuple_New(count));
1041-
}
1042-
bool err = false;
1043-
// transform QVariants to Python
1044-
for (int i = 0; i < count; i++) {
1045-
PyObject* arg = PythonQtConv::QVariantToPyObject(args.at(i));
1046-
if (arg) {
1047-
// steals reference, no unref
1048-
PyTuple_SetItem(pargs, i,arg);
1049-
} else {
1050-
err = true;
1051-
break;
1042+
1043+
// transform QVariant arguments to Python
1044+
for (int i = 0; i < count; i++) {
1045+
PyObject* arg = PythonQtConv::QVariantToPyObject(args.at(i));
1046+
if (arg) {
1047+
// steals reference, no unref
1048+
PyTuple_SetItem(pargs, i,arg);
1049+
} else {
1050+
err = true;
1051+
break;
1052+
}
10521053
}
10531054
}
1054-
10551055
if (!err) {
1056-
PyErr_Clear();
1057-
result = PyObject_CallObject(callable, pargs);
1056+
if (kwargs.isEmpty()) {
1057+
// do a direct call if we have no keyword arguments
1058+
PyErr_Clear();
1059+
result = PyObject_CallObject(callable, pargs);
1060+
} else {
1061+
// convert keyword arguments to Python
1062+
PythonQtObjectPtr pkwargs;
1063+
pkwargs.setNewRef(PyDict_New());
1064+
QMapIterator<QString, QVariant> it(kwargs);
1065+
while (it.hasNext()) {
1066+
it.next();
1067+
PyObject* arg = PythonQtConv::QVariantToPyObject(it.value());
1068+
if (arg) {
1069+
PyDict_SetItemString(pkwargs, it.key().toLatin1().constData(), arg);
1070+
} else {
1071+
err = true;
1072+
break;
1073+
}
1074+
}
1075+
if (!err) {
1076+
// call with arguments and keyword arguments
1077+
PyErr_Clear();
1078+
result = PyObject_Call(callable, pargs, pkwargs);
1079+
}
1080+
}
10581081
}
10591082
}
10601083
return result;

src/PythonQt.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,13 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
356356
//@{
357357

358358
//! call the given python \c callable in the scope of object, returns the result converted to a QVariant
359-
QVariant call(PyObject* object, const QString& callable, const QVariantList& args = QVariantList());
359+
QVariant call(PyObject* object, const QString& callable, const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
360360

361361
//! call the given python object, returns the result converted to a QVariant
362-
QVariant call(PyObject* callable, const QVariantList& args = QVariantList());
362+
QVariant call(PyObject* callable, const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
363363

364364
//! call the given python object, returns the result as new PyObject
365-
PyObject* callAndReturnPyObject(PyObject* callable, const QVariantList& args = QVariantList());
365+
PyObject* callAndReturnPyObject(PyObject* callable, const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
366366

367367
//@}
368368

src/PythonQtObjectPtr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ QVariant PythonQtObjectPtr::getVariable(const QString& name)
9696
}
9797

9898

99-
QVariant PythonQtObjectPtr::call(const QString& callable, const QVariantList& args)
99+
QVariant PythonQtObjectPtr::call(const QString& callable, const QVariantList& args, const QVariantMap& kwargs)
100100
{
101-
return PythonQt::self()->call(_object, callable, args);
101+
return PythonQt::self()->call(_object, callable, args, kwargs);
102102
}
103103

104-
QVariant PythonQtObjectPtr::call(const QVariantList& args)
104+
QVariant PythonQtObjectPtr::call(const QVariantList& args, const QVariantMap& kwargs)
105105
{
106-
return PythonQt::self()->call(_object, args);
106+
return PythonQt::self()->call(_object, args, kwargs);
107107
}
108108

109109
bool PythonQtObjectPtr::fromVariant(const QVariant& variant)

src/PythonQtObjectPtr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "PythonQtSystem.h"
4848
#include <QVariant>
4949
#include <QVariantList>
50+
#include <QVariantMap>
5051

5152
//! a smart pointer that stores a PyObject pointer and that handles reference counting automatically
5253
class PYTHONQT_EXPORT PythonQtObjectPtr
@@ -142,10 +143,10 @@ class PYTHONQT_EXPORT PythonQtObjectPtr
142143
QVariant getVariable(const QString& name);
143144

144145
//! call the given python object (in the scope of the current object), returns the result converted to a QVariant
145-
QVariant call(const QString& callable, const QVariantList& args = QVariantList());
146+
QVariant call(const QString& callable, const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
146147

147148
//! call the contained python object directly, returns the result converted to a QVariant
148-
QVariant call(const QVariantList& args = QVariantList());
149+
QVariant call(const QVariantList& args = QVariantList(), const QVariantMap& kwargs = QVariantMap());
149150

150151
protected:
151152

0 commit comments

Comments
 (0)