From 920249e8848a52abc49ba2eeee077ad952d098df Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 25 Jun 2025 13:37:51 -0500 Subject: [PATCH 1/4] chore: Remove deprecated Qt5 paradigms This changes deprecated Qt6 paradigms to either backward-compatible ones or uses preprocessor conditionals for Qt5 and Qt6 differences. This ensures compatibility with both Qt versions. Co-authored-by: Jean-Christophe Fillion-Robin --- src/PythonQtClassInfo.cpp | 4 ++ src/PythonQtConversion.cpp | 115 +++++++++++++++++++++----------- src/PythonQtConversion.h | 86 ++++++++++++++++++++++++ src/PythonQtInstanceWrapper.cpp | 16 +++++ src/PythonQtMethodInfo.cpp | 12 ++++ src/PythonQtSlot.cpp | 2 +- 6 files changed, 195 insertions(+), 40 deletions(-) diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 5e17f0d11..868b2240c 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -102,7 +102,11 @@ void PythonQtClassInfo::setupCPPObject(const QByteArray& classname) { _isQObject = false; _wrappedClassName = classname; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + _metaTypeId = QMetaType::fromName(classname).id(); +#else _metaTypeId = QMetaType::type(classname); +#endif if (_metaTypeId == 0) { _metaTypeId = -1; } diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index ca1313743..aaf8b1b7d 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -270,7 +270,11 @@ PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* dat default: // check if we have a QList of pointers, which we can circumvent with a QList if (info.isQList && (info.innerNamePointerCount == 1)) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static int id = QMetaType::fromName("QList").id(); +#else static int id = QMetaType::type("QList"); +#endif PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID(frame, id, ptr); // return the constData pointer that will be filled with the result value later on ptr = (void*)((QVariant*)ptr)->constData(); @@ -311,10 +315,17 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo { void* ptr = alreadyAllocatedCPPObject; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static int penId = QMetaType::fromName("QPen").id(); + static int brushId = QMetaType::fromName("QBrush").id(); + static int cursorId = QMetaType::fromName("QCursor").id(); + static int colorId = QMetaType::fromName("QColor").id(); +#else static int penId = QMetaType::type("QPen"); static int brushId = QMetaType::type("QBrush"); static int cursorId = QMetaType::type("QCursor"); static int colorId = QMetaType::type("QColor"); +#endif static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", nullptr); if (typeId == cursorId) { static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", nullptr); @@ -728,7 +739,11 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) { // check for QList case, where we will use a QList QVariant if (info.isQList && (info.innerNamePointerCount == 1)) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static int id = QMetaType::fromName("QList").id(); +#else static int id = QMetaType::type("QList"); +#endif if (!alreadyAllocatedCPPObject) { PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID_IF_NEEDED(alreadyAllocatedCPPObject, frame, id, ptr); ptr = (void*)((QVariant*)ptr)->constData(); @@ -1094,22 +1109,26 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) ) { // no special type requested if (val == nullptr) { - type = QVariant::Invalid; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + type = QMetaType::UnknownType; +#else + type = 0; // Equivalent to QVariant::Invalid or unregistered type +#endif } else if (PyBytes_Check(val)) { #ifdef PY3K // In Python 3, it is a ByteArray - type = QVariant::ByteArray; + type = QMetaType::QByteArray; #else // In Python 2, we need to use String, since it might be a string - type = QVariant::String; + type = QMetaType::QString; #endif } else if (PyUnicode_Check(val)) { - type = QVariant::String; + type = QMetaType::QString; } else if (val == Py_False || val == Py_True) { - type = QVariant::Bool; + type = QMetaType::Bool; #ifndef PY3K } else if (PyObject_TypeCheck(val, &PyInt_Type)) { - type = QVariant::Int; + type = QMetaType::Int; #endif } else if (PyLong_Check(val)) { // return int if the value fits into that range, @@ -1117,12 +1136,12 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) qint64 d = PyLong_AsLongLong(val); if (d > std::numeric_limits::max() || d < std::numeric_limits::min()) { - type = QVariant::LongLong; + type = QMetaType::LongLong; } else { - type = QVariant::Int; + type = QMetaType::Int; } } else if (PyFloat_Check(val)) { - type = QVariant::Double; + type = QMetaType::Double; } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) { PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val; // c++ wrapper, check if the class names of the c++ objects match @@ -1144,11 +1163,15 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) return v; } else if (val == Py_None) { // none is invalid - type = QVariant::Invalid; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + type = QMetaType::UnknownType; +#else + type = 0; // Equivalent to QVariant::Invalid or unregistered type +#endif } else if (PyDict_Check(val)) { - type = QVariant::Map; + type = QMetaType::QVariantMap; } else if (PyList_Check(val) || PyTuple_Check(val) || PySequence_Check(val)) { - type = QVariant::List; + type = QMetaType::QVariantList; } else { // transport the Python objects directly inside of QVariant: v = PythonQtObjectPtr(val).toVariant(); @@ -1157,28 +1180,32 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } // special type request: switch (type) { - case QVariant::Invalid: +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + case QMetaType::UnknownType: +#else + case 0: // Equivalent to QVariant::Invalid or unregistered type +#endif return v; break; - case QVariant::Int: + case QMetaType::Int: { int d = PyObjGetInt(val, false, ok); if (ok) return QVariant(d); } break; - case QVariant::UInt: + case QMetaType::UInt: { int d = PyObjGetInt(val, false,ok); if (ok) v = QVariant((unsigned int)d); } break; - case QVariant::Bool: + case QMetaType::Bool: { int d = PyObjGetBool(val,false,ok); if (ok) v = QVariant((bool)(d!=0)); } break; - case QVariant::Double: + case QMetaType::Double: { double d = PyObjGetDouble(val,false,ok); if (ok) v = QVariant(d); @@ -1239,7 +1266,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } break; - case QVariant::ByteArray: + case QMetaType::QByteArray: { bool ok; #ifdef PY3K @@ -1249,20 +1276,20 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) #endif } break; - case QVariant::String: + case QMetaType::QString: { bool ok; v = QVariant(PyObjGetString(val, false, ok)); } break; - case QVariant::Map: + case QMetaType::QVariantMap: pythonToMapVariant(val, v); break; - case QVariant::Hash: + case QMetaType::QVariantHash: pythonToMapVariant(val, v); break; - case QVariant::List: + case QMetaType::QVariantList: { bool isListOrTuple = PyList_Check(val) || PyTuple_Check(val); if (isListOrTuple || PySequence_Check(val)) { @@ -1288,7 +1315,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } } break; - case QVariant::StringList: + case QMetaType::QStringList: { bool ok; QStringList l = PyObjToStringList(val, false, ok); @@ -1308,7 +1335,11 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) // Try to convert the object to a QVariant based on the typeName bool ok; bool isPtr = false; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QByteArray typeName = QMetaType(type).name(); +#else QByteArray typeName = QMetaType::typeName(type); +#endif if (typeName.endsWith("*")) { isPtr = true; typeName.truncate(typeName.length() - 1); @@ -1323,7 +1354,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } } } - } else if (static_cast(type) >= QVariant::UserType) { + } else if (static_cast(type) >= QMetaType::User) { // not an instance wrapper, but there might be other converters // Maybe we have a special converter that is registered for that type: PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(type); @@ -1505,66 +1536,66 @@ bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList(data); r = QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::SizeF: { + case QMetaType::QSizeF: { const QSizeF* s = static_cast(data); r = QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Point: { + case QMetaType::QPoint: { const QPoint* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); } break; - case QVariant::PointF: { + case QMetaType::QPointF: { const QPointF* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); } break; - case QVariant::Rect: { + case QMetaType::QRect: { const QRect* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); r += ", " + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::RectF: { + case QMetaType::QRectF: { const QRectF* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); r += ", " + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Date: { + case QMetaType::QDate: { const QDate* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::DateTime: { + case QMetaType::QDateTime: { const QDateTime* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::Time: { + case QMetaType::QTime: { const QTime* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::Pixmap: + case QMetaType::QPixmap: { const QPixmap* s = static_cast(data); r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Image: + case QMetaType::QImage: { const QImage* s = static_cast(data); r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Url: + case QMetaType::QUrl: { const QUrl* s = static_cast(data); r = s->toString(); @@ -1574,7 +1605,7 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { default: // this creates a copy, but that should not be expensive for typical simple variants // (but we do not want to do this for our own user types!) - if (type>0 && type < (int)QVariant::UserType) { + if (type>0 && type < (int)QMetaType::User) { r = variantFromType(type, data).toString(); } } @@ -1584,13 +1615,19 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data ) { // if the type is known, we can construct it via QMetaType::construct -#if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) ) +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + void* newCPPObject = QMetaType(type).create(data); + // XXX this could be optimized by using metatypeid directly + PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType(type).name()); +#elif QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) void* newCPPObject = QMetaType::create(type, data); + // XXX this could be optimized by using metatypeid directly + PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); #else void* newCPPObject = QMetaType::construct(type, data); -#endif // XXX this could be optimized by using metatypeid directly PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); +#endif wrap->_ownedByPythonQt = true; wrap->_useQMetaTypeDestroy = true; return (PyObject*)wrap; diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index d0f0eeb16..8f0ae69a2 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -237,9 +237,15 @@ template PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; +#else static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; +#endif } PyObject* result = PyTuple_New(list->size()); int i = 0; @@ -254,9 +260,15 @@ template bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; +#else static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; +#endif } bool result = false; if (PySequence_Check(obj)) { @@ -287,10 +299,17 @@ template PyObject* PythonQtConvertListOfKnownClassToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); + if (innerType == nullptr) { + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; + } +#else static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); if (innerType == nullptr) { std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(list->size()); int i = 0; Q_FOREACH(const T& value, *list) { @@ -307,10 +326,17 @@ template bool PythonQtConvertPythonListToListOfKnownClass(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); + if (innerType == nullptr) { + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; + } +#else static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); if (innerType == nullptr) { std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -350,14 +376,27 @@ PyObject* PythonQtConvertPairToPython(const void* /*QPair* */ inPair, int static int innerType1 = -1; static int innerType2 = -1; if (innerType1==-1) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); + innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType1 = QMetaType::type(names.at(0).trimmed()); innerType2 = QMetaType::type(names.at(1).trimmed()); +#endif } +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(2); PyTuple_SET_ITEM(result, 0, PythonQtConv::convertQtValueToPythonInternal(innerType1, &pair->first)); PyTuple_SET_ITEM(result, 1, PythonQtConv::convertQtValueToPythonInternal(innerType2, &pair->second)); @@ -371,14 +410,27 @@ bool PythonQtConvertPythonToPair(PyObject* obj, void* /*QPair* */ outPair static int innerType1 = -1; static int innerType2 = -1; if (innerType1 == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); + innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType1 = QMetaType::type(names.at(0).trimmed()); innerType2 = QMetaType::type(names.at(1).trimmed()); +#endif + } +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; } +#else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -416,10 +468,17 @@ template PyObject* PythonQtConvertListOfPairToPythonList(const void* /*QList >* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(list->size()); int i = 0; typedef const QPair Pair; @@ -435,10 +494,17 @@ template bool PythonQtConvertPythonListToListOfPair(PyObject* obj, void* /*QList >* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -470,6 +536,15 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap MapType* map = (MapType*)inMap; static int innerType = -1; if (innerType == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + } + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType = QMetaType::type(names.at(1).trimmed()); @@ -477,6 +552,7 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyDict_New(); typename MapType::const_iterator t = map->constBegin(); @@ -498,6 +574,15 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o MapType* map = (MapType*)outMap; static int innerType = -1; if (innerType == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + } + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType = QMetaType::type(names.at(1).trimmed()); @@ -505,6 +590,7 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PyMapping_Check(val)) { result = true; diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp index c560810ab..8c84499b0 100644 --- a/src/PythonQtInstanceWrapper.cpp +++ b/src/PythonQtInstanceWrapper.cpp @@ -70,7 +70,11 @@ static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, int type = self->classInfo()->metaTypeId(); if (self->_useQMetaTypeDestroy && type>=0) { // use QMetaType to destroy the object +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QMetaType(type).destroy(self->_wrappedPtr); +#else QMetaType::destroy(type, self->_wrappedPtr); +#endif } else { PythonQtSlotInfo* slot = self->classInfo()->destructor(); if (slot) { @@ -82,7 +86,11 @@ static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, } else { if (type>=0) { // use QMetaType to destroy the object +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QMetaType(type).destroy(self->_wrappedPtr); +#else QMetaType::destroy(type, self->_wrappedPtr); +#endif } else { // TODO: warn about not being able to destroy the object? } @@ -482,7 +490,11 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) switch (member._type) { case PythonQtMemberInfo::Property: if (wrapper->_obj) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + if (member._property.userType() != QMetaType::UnknownType) { +#else if (member._property.userType() != QVariant::Invalid) { +#endif PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB(); if (profilingCB) { @@ -762,7 +774,11 @@ static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; // QByteArray should be directly returned as a str +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + if (wrapper->classInfo()->metaTypeId() == QMetaType::QByteArray) { +#else if (wrapper->classInfo()->metaTypeId()==QVariant::ByteArray) { +#endif QByteArray* b = (QByteArray*) wrapper->_wrappedPtr; #ifdef PY3K // Note: In Python 2, this was used to access the data() of a byte array. diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index f428ce5f2..16908d2c5 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -191,7 +191,11 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray type.typeId = nameToType(name); if (type.typeId == Unknown) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + type.typeId = QMetaType::fromName(name.constData()).id(); +#else type.typeId = QMetaType::type(name.constData()); +#endif #if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) ) if (type.typeId == QMetaType::UnknownType) { #else @@ -234,7 +238,11 @@ int PythonQtMethodInfo::getInnerTemplateMetaType(const QByteArray& typeName) int idx2 = typeName.lastIndexOf(">"); if (idx2 > 0) { QByteArray innerType = typeName.mid(idx + 1, idx2 - idx - 1).trimmed(); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + return QMetaType::fromName(innerType.constData()).id(); +#else return QMetaType::type(innerType.constData()); +#endif } } return QMetaType::Void; @@ -442,7 +450,11 @@ const PythonQtMethodInfo::ParameterInfo& PythonQtMethodInfo::getParameterInfoFor return it.value(); } ParameterInfo info; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + fillParameterInfo(info, QMetaType(type).name()); +#else fillParameterInfo(info, QMetaType::typeName(type)); +#endif _cachedParameterInfos.insert(type, info); return _cachedParameterInfos[type]; } diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp index 084df8706..a502be4b6 100644 --- a/src/PythonQtSlot.cpp +++ b/src/PythonQtSlot.cpp @@ -553,7 +553,7 @@ meth_get__doc__(PythonQtSlotFunctionObject * m, void * /*closure*/) } else if (returnType.startsWith("QHash<") || returnType.startsWith("QMap<") || returnType == "QVariantMap" || returnType == "QVariantHash") { pyReturnType = "dict"; - } else if (returnTypeId == QVariant::Bool) { + } else if (returnTypeId == QMetaType::Bool) { pyReturnType = "bool"; } else if (returnTypeId == PythonQtMethodInfo::Variant) { pyReturnType = "object"; From 25219b8a0f15041eba7f40e35e334688e2823460 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 28 Aug 2025 04:16:43 -0400 Subject: [PATCH 2/4] chore: Simplify Qt6 support introducing PythonQtUtils helpers This change introduces utility functions in PythonQtUtils to simplify and centralize handling differences between Qt5 and Qt6. Suggested-by: mrbean-bremen --- src/PythonQtClassInfo.cpp | 6 +- src/PythonQtConversion.cpp | 41 +++---------- src/PythonQtConversion.h | 122 +++++++++++-------------------------- src/PythonQtMethodInfo.cpp | 18 +----- src/PythonQtUtils.h | 19 ++++++ 5 files changed, 66 insertions(+), 140 deletions(-) diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 868b2240c..9e4524a6a 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -102,11 +102,7 @@ void PythonQtClassInfo::setupCPPObject(const QByteArray& classname) { _isQObject = false; _wrappedClassName = classname; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - _metaTypeId = QMetaType::fromName(classname).id(); -#else - _metaTypeId = QMetaType::type(classname); -#endif + _metaTypeId = PythonQtUtils::metaTypeIdFromTypeName(classname); if (_metaTypeId == 0) { _metaTypeId = -1; } diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index aaf8b1b7d..36388050f 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -270,11 +270,7 @@ PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* dat default: // check if we have a QList of pointers, which we can circumvent with a QList if (info.isQList && (info.innerNamePointerCount == 1)) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static int id = QMetaType::fromName("QList").id(); -#else - static int id = QMetaType::type("QList"); -#endif + static int id = PythonQtUtils::metaTypeIdFromTypeName("QList"); PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID(frame, id, ptr); // return the constData pointer that will be filled with the result value later on ptr = (void*)((QVariant*)ptr)->constData(); @@ -315,17 +311,10 @@ void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, vo { void* ptr = alreadyAllocatedCPPObject; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static int penId = QMetaType::fromName("QPen").id(); - static int brushId = QMetaType::fromName("QBrush").id(); - static int cursorId = QMetaType::fromName("QCursor").id(); - static int colorId = QMetaType::fromName("QColor").id(); -#else - static int penId = QMetaType::type("QPen"); - static int brushId = QMetaType::type("QBrush"); - static int cursorId = QMetaType::type("QCursor"); - static int colorId = QMetaType::type("QColor"); -#endif + static int penId = PythonQtUtils::metaTypeIdFromTypeName("QPen"); + static int brushId = PythonQtUtils::metaTypeIdFromTypeName("QBrush"); + static int cursorId = PythonQtUtils::metaTypeIdFromTypeName("QCursor"); + static int colorId = PythonQtUtils::metaTypeIdFromTypeName("QColor"); static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", nullptr); if (typeId == cursorId) { static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", nullptr); @@ -739,11 +728,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) { // check for QList case, where we will use a QList QVariant if (info.isQList && (info.innerNamePointerCount == 1)) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static int id = QMetaType::fromName("QList").id(); -#else - static int id = QMetaType::type("QList"); -#endif + static int id = PythonQtUtils::metaTypeIdFromTypeName("QList"); if (!alreadyAllocatedCPPObject) { PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID_IF_NEEDED(alreadyAllocatedCPPObject, frame, id, ptr); ptr = (void*)((QVariant*)ptr)->constData(); @@ -1335,11 +1320,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) // Try to convert the object to a QVariant based on the typeName bool ok; bool isPtr = false; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - QByteArray typeName = QMetaType(type).name(); -#else - QByteArray typeName = QMetaType::typeName(type); -#endif + QByteArray typeName = QByteArray(PythonQtUtils::typeNameFromMetaTypeId(type)); if (typeName.endsWith("*")) { isPtr = true; typeName.truncate(typeName.length() - 1); @@ -1617,17 +1598,13 @@ PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data ) // if the type is known, we can construct it via QMetaType::construct #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) void* newCPPObject = QMetaType(type).create(data); - // XXX this could be optimized by using metatypeid directly - PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType(type).name()); #elif QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) void* newCPPObject = QMetaType::create(type, data); - // XXX this could be optimized by using metatypeid directly - PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); #else void* newCPPObject = QMetaType::construct(type, data); - // XXX this could be optimized by using metatypeid directly - PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); #endif + // XXX this could be optimized by using metatypeid directly + PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QByteArray(PythonQtUtils::typeNameFromMetaTypeId(type))); wrap->_ownedByPythonQt = true; wrap->_useQMetaTypeDestroy = true; return (PyObject*)wrap; diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index 8f0ae69a2..8864276cb 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -237,15 +237,13 @@ template PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; #else - static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; #endif + std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } PyObject* result = PyTuple_New(list->size()); int i = 0; @@ -260,15 +258,13 @@ template bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; #else - static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; #endif + std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } bool result = false; if (PySequence_Check(obj)) { @@ -299,17 +295,10 @@ template PyObject* PythonQtConvertListOfKnownClassToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); - if (innerType == nullptr) { - std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; - } -#else - static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId)))); if (innerType == nullptr) { - std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } -#endif PyObject* result = PyTuple_New(list->size()); int i = 0; Q_FOREACH(const T& value, *list) { @@ -326,17 +315,10 @@ template bool PythonQtConvertPythonListToListOfKnownClass(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId)))); if (innerType == nullptr) { - std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } -#else - static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); - if (innerType == nullptr) { - std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; - } -#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -376,27 +358,18 @@ PyObject* PythonQtConvertPairToPython(const void* /*QPair* */ inPair, int static int innerType1 = -1; static int innerType2 = -1; if (innerType1==-1) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); QList names = innerTypes.split(','); - innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); - innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); -#else - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); - QList names = innerTypes.split(','); - innerType1 = QMetaType::type(names.at(0).trimmed()); - innerType2 = QMetaType::type(names.at(1).trimmed()); -#endif + innerType1 = PythonQtUtils::metaTypeIdFromTypeName(names.at(0).trimmed()); + innerType2 = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { - std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertPairToPython: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } PyObject* result = PyTuple_New(2); PyTuple_SET_ITEM(result, 0, PythonQtConv::convertQtValueToPythonInternal(innerType1, &pair->first)); PyTuple_SET_ITEM(result, 1, PythonQtConv::convertQtValueToPythonInternal(innerType2, &pair->second)); @@ -410,27 +383,18 @@ bool PythonQtConvertPythonToPair(PyObject* obj, void* /*QPair* */ outPair static int innerType1 = -1; static int innerType2 = -1; if (innerType1 == -1) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); - QList names = innerTypes.split(','); - innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); - innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); -#else - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); QList names = innerTypes.split(','); - innerType1 = QMetaType::type(names.at(0).trimmed()); - innerType2 = QMetaType::type(names.at(1).trimmed()); -#endif + innerType1 = PythonQtUtils::metaTypeIdFromTypeName(names.at(0).trimmed()); + innerType2 = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { - std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -468,17 +432,14 @@ template PyObject* PythonQtConvertListOfPairToPythonList(const void* /*QList >* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else - static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } PyObject* result = PyTuple_New(list->size()); int i = 0; typedef const QPair Pair; @@ -494,17 +455,14 @@ template bool PythonQtConvertPythonListToListOfPair(PyObject* obj, void* /*QList >* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else - static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -536,23 +494,17 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap MapType* map = (MapType*)inMap; static int innerType = -1; if (innerType == -1) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); QList names = innerTypes.split(','); - innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + innerType = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); - QList names = innerTypes.split(','); - innerType = QMetaType::type(names.at(1).trimmed()); - } if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } PyObject* result = PyDict_New(); typename MapType::const_iterator t = map->constBegin(); @@ -574,23 +526,17 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o MapType* map = (MapType*)outMap; static int innerType = -1; if (innerType == -1) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); QList names = innerTypes.split(','); - innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + innerType = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { - std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; - } #else - QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); - QList names = innerTypes.split(','); - innerType = QMetaType::type(names.at(1).trimmed()); - } if (innerType == QVariant::Invalid) { - std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; - } #endif + std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; + } bool result = false; if (PyMapping_Check(val)) { result = true; diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index 16908d2c5..0653fee94 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -191,11 +191,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray type.typeId = nameToType(name); if (type.typeId == Unknown) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - type.typeId = QMetaType::fromName(name.constData()).id(); -#else - type.typeId = QMetaType::type(name.constData()); -#endif + type.typeId = PythonQtUtils::metaTypeIdFromTypeName(name.constData()); #if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) ) if (type.typeId == QMetaType::UnknownType) { #else @@ -238,11 +234,7 @@ int PythonQtMethodInfo::getInnerTemplateMetaType(const QByteArray& typeName) int idx2 = typeName.lastIndexOf(">"); if (idx2 > 0) { QByteArray innerType = typeName.mid(idx + 1, idx2 - idx - 1).trimmed(); -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - return QMetaType::fromName(innerType.constData()).id(); -#else - return QMetaType::type(innerType.constData()); -#endif + return PythonQtUtils::metaTypeIdFromTypeName(innerType.constData()); } } return QMetaType::Void; @@ -450,11 +442,7 @@ const PythonQtMethodInfo::ParameterInfo& PythonQtMethodInfo::getParameterInfoFor return it.value(); } ParameterInfo info; -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - fillParameterInfo(info, QMetaType(type).name()); -#else - fillParameterInfo(info, QMetaType::typeName(type)); -#endif + fillParameterInfo(info, QByteArray(PythonQtUtils::typeNameFromMetaTypeId(type))); _cachedParameterInfos.insert(type, info); return _cachedParameterInfos[type]; } diff --git a/src/PythonQtUtils.h b/src/PythonQtUtils.h index 50692d47b..4c908bd72 100644 --- a/src/PythonQtUtils.h +++ b/src/PythonQtUtils.h @@ -47,6 +47,7 @@ #include #include +#include namespace PythonQtUtils { @@ -89,6 +90,24 @@ namespace PythonQtUtils #else // support old-style classes and new style classes return (obj->ob_type == &PyClass_Type || obj->ob_type == &PyType_Type); +#endif + } + + //! Returns the meta type ID from a type name + inline int metaTypeIdFromTypeName(const QByteArray& className) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + return QMetaType::fromName(className.constData()).id(); +#else + return QMetaType::type(className.constData()); +#endif + } + + //! Returns the type name from a meta type ID + inline const char * typeNameFromMetaTypeId(int metaTypeId) { +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + return QMetaType(metaTypeId).name(); +#else + return QMetaType::typeName(metaTypeId); #endif } } From 69f59adbe4948280f4ca45fad7e565ad361dc924 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 28 Aug 2025 05:42:11 -0400 Subject: [PATCH 3/4] chore: Consistently use QMetaType::UnknownType --- src/PythonQtConversion.cpp | 18 +++--------------- src/PythonQtConversion.h | 32 -------------------------------- src/PythonQtInstanceWrapper.cpp | 4 ---- 3 files changed, 3 insertions(+), 51 deletions(-) diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index 36388050f..455a0d2dc 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -1094,11 +1094,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) ) { // no special type requested if (val == nullptr) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - type = QMetaType::UnknownType; -#else - type = 0; // Equivalent to QVariant::Invalid or unregistered type -#endif + type = QMetaType::UnknownType; // Equivalent to QVariant::Invalid or unregistered type } else if (PyBytes_Check(val)) { #ifdef PY3K // In Python 3, it is a ByteArray @@ -1148,11 +1144,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) return v; } else if (val == Py_None) { // none is invalid -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - type = QMetaType::UnknownType; -#else - type = 0; // Equivalent to QVariant::Invalid or unregistered type -#endif + type = QMetaType::UnknownType; // Equivalent to QVariant::Invalid or unregistered type } else if (PyDict_Check(val)) { type = QMetaType::QVariantMap; } else if (PyList_Check(val) || PyTuple_Check(val) || PySequence_Check(val)) { @@ -1165,11 +1157,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } // special type request: switch (type) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - case QMetaType::UnknownType: -#else - case 0: // Equivalent to QVariant::Invalid or unregistered type -#endif + case QMetaType::UnknownType: // Equivalent to QVariant::Invalid or unregistered type return v; break; case QMetaType::Int: diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index 8864276cb..56fc11471 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -238,11 +238,7 @@ PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList* */ { ListType* list = (ListType*)inList; static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } PyObject* result = PyTuple_New(list->size()); @@ -259,11 +255,7 @@ bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList* { ListType* list = (ListType*)outList; static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } bool result = false; @@ -363,11 +355,7 @@ PyObject* PythonQtConvertPairToPython(const void* /*QPair* */ inPair, int innerType1 = PythonQtUtils::metaTypeIdFromTypeName(names.at(0).trimmed()); innerType2 = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { -#else - if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertPairToPython: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } PyObject* result = PyTuple_New(2); @@ -388,11 +376,7 @@ bool PythonQtConvertPythonToPair(PyObject* obj, void* /*QPair* */ outPair innerType1 = PythonQtUtils::metaTypeIdFromTypeName(names.at(0).trimmed()); innerType2 = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { -#else - if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } bool result = false; @@ -433,11 +417,7 @@ PyObject* PythonQtConvertListOfPairToPythonList(const void* /*QList { ListType* list = (ListType*)inList; static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(PythonQtUtils::typeNameFromMetaTypeId(metaTypeId))); -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } PyObject* result = PyTuple_New(list->size()); @@ -456,11 +436,7 @@ bool PythonQtConvertPythonListToListOfPair(PyObject* obj, void* /*QList= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } bool result = false; @@ -498,11 +474,7 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap QList names = innerTypes.split(','); innerType = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } @@ -530,11 +502,7 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o QList names = innerTypes.split(','); innerType = PythonQtUtils::metaTypeIdFromTypeName(names.at(1).trimmed()); } -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (innerType == QMetaType::UnknownType) { -#else - if (innerType == QVariant::Invalid) { -#endif std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << PythonQtUtils::typeNameFromMetaTypeId(metaTypeId) << std::endl; } bool result = false; diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp index 8c84499b0..ccdd64719 100644 --- a/src/PythonQtInstanceWrapper.cpp +++ b/src/PythonQtInstanceWrapper.cpp @@ -490,11 +490,7 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) switch (member._type) { case PythonQtMemberInfo::Property: if (wrapper->_obj) { -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (member._property.userType() != QMetaType::UnknownType) { -#else - if (member._property.userType() != QVariant::Invalid) { -#endif PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB(); if (profilingCB) { From 87df4f2bd507dd6607faf0e14e3824a2ad45b7b3 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Thu, 28 Aug 2025 06:15:41 -0400 Subject: [PATCH 4/4] chore: Consistently use QMetaType::QByteArray --- src/PythonQtInstanceWrapper.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp index ccdd64719..11ca09d64 100644 --- a/src/PythonQtInstanceWrapper.cpp +++ b/src/PythonQtInstanceWrapper.cpp @@ -770,11 +770,7 @@ static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; // QByteArray should be directly returned as a str -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) if (wrapper->classInfo()->metaTypeId() == QMetaType::QByteArray) { -#else - if (wrapper->classInfo()->metaTypeId()==QVariant::ByteArray) { -#endif QByteArray* b = (QByteArray*) wrapper->_wrappedPtr; #ifdef PY3K // Note: In Python 2, this was used to access the data() of a byte array.