@@ -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;
0 commit comments