@@ -85,22 +85,18 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
8585 return Py_None;
8686 }
8787 } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
88- info.name .startsWith (" QList<" )) {
89- // it is a QList template:
90- QByteArray innerType = info.name .mid (6 ,info.name .length ()-7 );
91- if (innerType.endsWith (" *" )) {
92- innerType.truncate (innerType.length ()-1 );
93- QList<void *>* listPtr = NULL ;
94- if (info.pointerCount == 1 ) {
95- listPtr = *((QList<void *>**)data);
96- } else if (info.pointerCount == 0 ) {
97- listPtr = (QList<void *>*)data;
98- }
99- if (listPtr) {
100- return ConvertQListOfPointerTypeToPythonList (listPtr, innerType);
101- } else {
102- return NULL ;
103- }
88+ info.isQList && (info.innerNamePointerCount == 1 )) {
89+ // it is a QList<Obj*> template:
90+ QList<void *>* listPtr = NULL ;
91+ if (info.pointerCount == 1 ) {
92+ listPtr = *((QList<void *>**)data);
93+ } else if (info.pointerCount == 0 ) {
94+ listPtr = (QList<void *>*)data;
95+ }
96+ if (listPtr) {
97+ return ConvertQListOfPointerTypeToPythonList (listPtr, info.innerName );
98+ } else {
99+ return NULL ;
104100 }
105101 }
106102
@@ -208,9 +204,9 @@ PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* dat
208204 }
209205 std::cerr << " Unknown type that can not be converted to Python: " << type << " , in " << __FILE__ << " :" << __LINE__ << std::endl;
210206 }
211- }
212- Py_INCREF (Py_None);
213- return Py_None;
207+ }
208+ Py_INCREF (Py_None);
209+ return Py_None;
214210 }
215211
216212 void * PythonQtConv::CreateQtReturnValue (const PythonQtMethodInfo::ParameterInfo& info) {
@@ -243,20 +239,15 @@ return Py_None;
243239 // return the ptr to the variant
244240 break ;
245241 default :
246- if (info.typeId == PythonQtMethodInfo::Unknown) {
247- // check if we have a QList of pointers, which we can circumvent with a QList<void*>
248- if (info.name .startsWith (" QList<" )) {
249- QByteArray innerType = info.name .mid (6 ,info.name .length ()-7 );
250- if (innerType.endsWith (" *" )) {
251- static int id = QMetaType::type (" QList<void*>" );
252- PythonQtValueStorage_ADD_VALUE (global_variantStorage, QVariant, QVariant::Type (id), ptr);
253- // return the constData pointer that will be filled with the result value later on
254- ptr = (void *)((QVariant*)ptr)->constData ();
255- }
256- }
242+ // check if we have a QList of pointers, which we can circumvent with a QList<void*>
243+ if (info.isQList && (info.innerNamePointerCount == 1 )) {
244+ static int id = QMetaType::type (" QList<void*>" );
245+ PythonQtValueStorage_ADD_VALUE (global_variantStorage, QVariant, QVariant::Type (id), ptr);
246+ // return the constData pointer that will be filled with the result value later on
247+ ptr = (void *)((QVariant*)ptr)->constData ();
257248 }
258249
259- if (!ptr && info.typeId != PythonQtMethodInfo::Unknown) {
250+ if (!ptr && info.typeId != PythonQtMethodInfo::Unknown) {
260251 // everything else is stored in a QVariant, if we know the meta type...
261252 PythonQtValueStorage_ADD_VALUE (global_variantStorage, QVariant, QVariant::Type (info.typeId ), ptr);
262253 // return the constData pointer that will be filled with the result value later on
@@ -631,23 +622,19 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
631622
632623 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
633624 // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
634- if (info.name .startsWith (" QList<" )) {
635- QByteArray innerType = info.name .mid (6 ,info.name .length ()-7 );
636- if (innerType.endsWith (" *" )) {
637- innerType.truncate (innerType.length ()-1 );
638- static int id = QMetaType::type (" QList<void*>" );
639- if (!alreadyAllocatedCPPObject) {
640- PythonQtValueStorage_ADD_VALUE_IF_NEEDED (alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type (id), ptr);
641- ptr = (void *)((QVariant*)ptr)->constData ();
642- } else {
643- ptr = alreadyAllocatedCPPObject;
644- }
645- ok = ConvertPythonListToQListOfPointerType (obj, (QList<void *>*)ptr, innerType, strict);
646- if (ok) {
647- return ptr;
648- } else {
649- return NULL ;
650- }
625+ if (info.isQList && (info.innerNamePointerCount == 1 )) {
626+ static int id = QMetaType::type (" QList<void*>" );
627+ if (!alreadyAllocatedCPPObject) {
628+ PythonQtValueStorage_ADD_VALUE_IF_NEEDED (alreadyAllocatedCPPObject, global_variantStorage, QVariant, QVariant::Type (id), ptr);
629+ ptr = (void *)((QVariant*)ptr)->constData ();
630+ } else {
631+ ptr = alreadyAllocatedCPPObject;
632+ }
633+ ok = ConvertPythonListToQListOfPointerType (obj, (QList<void *>*)ptr, info.innerName , strict);
634+ if (ok) {
635+ return ptr;
636+ } else {
637+ return NULL ;
651638 }
652639 }
653640 }
@@ -1138,10 +1125,48 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
11381125 // construct a new variant from the C++ object if it has the same meta type
11391126 v = QVariant (type, wrap->_wrappedPtr );
11401127 } else {
1141- v = QVariant ();
1128+ // Try to convert the object to a QVariant based on the typeName
1129+ bool ok;
1130+ bool isPtr = false ;
1131+ QByteArray typeName = QMetaType::typeName (type);
1132+ if (typeName.endsWith (" *" )) {
1133+ isPtr = true ;
1134+ typeName.truncate (typeName.length () - 1 );
1135+ }
1136+ void * object = castWrapperTo (wrap, typeName, ok);
1137+ if (ok) {
1138+ if (isPtr) {
1139+ v = QVariant (type, &object);
1140+ }
1141+ else {
1142+ v = QVariant (type, object);
1143+ }
1144+ }
1145+ }
1146+ } else if (type >= QVariant::UserType) {
1147+ // not an instance wrapper, but there might be other converters
1148+ // Maybe we have a special converter that is registered for that type:
1149+ PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value (type);
1150+ if (converter) {
1151+ // allocate a default object of the needed type:
1152+ v = QVariant (type, NULL );
1153+ // now call the converter, passing the internal object of the variant
1154+ ok = (*converter)(val, (void *)v.constData (), type, true );
1155+ if (!ok) {
1156+ v = QVariant ();
1157+ }
1158+ } else {
1159+ // try QList<AnyObject*>...
1160+ const PythonQtMethodInfo::ParameterInfo& info = PythonQtMethodInfo::getParameterInfoForMetaType (type);
1161+ if (info.isQList && (info.innerNamePointerCount == 1 )) {
1162+ // allocate a default object of the needed type:
1163+ v = QVariant (type, NULL );
1164+ ok = ConvertPythonListToQListOfPointerType (val, (QList<void *>*)v.constData (), info.innerName , true );
1165+ if (!ok) {
1166+ v = QVariant ();
1167+ }
1168+ }
11421169 }
1143- } else {
1144- v = QVariant ();
11451170 }
11461171 }
11471172 return v;
@@ -1183,7 +1208,20 @@ PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
11831208
11841209PyObject* PythonQtConv::QVariantToPyObject (const QVariant& v)
11851210{
1186- return ConvertQtValueToPythonInternal (v.userType (), (void *)v.constData ());
1211+ if (!v.isValid ()) {
1212+ Py_INCREF (Py_None);
1213+ return Py_None;
1214+ }
1215+ PyObject* obj = NULL ;
1216+ if (v.userType () >= QMetaType::User && !PythonQt::priv ()->isPythonQtObjectPtrMetaId (v.userType ())) {
1217+ // try the slower way, which supports more conversions, e.g. QList<QObject*>
1218+ const PythonQtMethodInfo::ParameterInfo& info = PythonQtMethodInfo::getParameterInfoForMetaType (v.userType ());
1219+ obj = ConvertQtValueToPython (info, v.constData ());
1220+ } else {
1221+ // try the quick way to convert it, since it is a built-in type:
1222+ obj = ConvertQtValueToPythonInternal (v.userType (), (void *)v.constData ());
1223+ }
1224+ return obj;
11871225}
11881226
11891227template <typename Map>
@@ -1262,31 +1300,6 @@ bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<vo
12621300 return result;
12631301}
12641302
1265- int PythonQtConv::getInnerTemplateMetaType (const QByteArray& typeName)
1266- {
1267- int idx = typeName.indexOf (" <" );
1268- if (idx>0 ) {
1269- int idx2 = typeName.lastIndexOf (" >" );
1270- if (idx2>0 ) {
1271- QByteArray innerType = typeName.mid (idx+1 ,idx2-idx-1 ).trimmed ();
1272- return QMetaType::type (innerType.constData ());
1273- }
1274- }
1275- return QMetaType::Void;
1276- }
1277-
1278- QByteArray PythonQtConv::getInnerTemplateTypeName (const QByteArray& typeName)
1279- {
1280- int idx = typeName.indexOf (" <" );
1281- if (idx > 0 ) {
1282- int idx2 = typeName.lastIndexOf (" >" );
1283- if (idx2 > 0 ) {
1284- return typeName.mid (idx + 1 , idx2 - idx - 1 ).trimmed ();
1285- }
1286- }
1287- return QByteArray ();
1288- }
1289-
12901303
12911304QString PythonQtConv::CPPObjectToString (int type, const void * data) {
12921305 QString r;
0 commit comments