Skip to content

Commit 8769ef4

Browse files
usiemsmrbean-bremen
authored andcommitted
Handle QStringView et al as argument/return value
1 parent e56ceda commit 8769ef4

File tree

4 files changed

+111
-7
lines changed

4 files changed

+111
-7
lines changed

generator/typesystem.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,14 @@ TypeDatabase::TypeDatabase() : m_suppressWarnings(true)
15191519
e->setPreferredConversion(false);
15201520
addType(e);
15211521

1522+
e = new StringTypeEntry("QStringView");
1523+
e->setPreferredConversion(false);
1524+
addType(e);
1525+
1526+
e = new StringTypeEntry("QAnyStringView");
1527+
e->setPreferredConversion(false);
1528+
addType(e);
1529+
15221530
e = new StringTypeEntry("QXmlStreamStringRef");
15231531
e->setPreferredConversion(false);
15241532
addType(e);

src/PythonQt.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,7 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
122122
} else {
123123
qRegisterMetaType<quint32>("size_t");
124124
}
125-
#if QT_VERSION < 0x060000
126-
int stringRefId = qRegisterMetaType<QStringRef>("QStringRef");
127-
PythonQtConv::registerMetaTypeToPythonConverter(stringRefId, PythonQtConv::convertFromStringRef);
128-
#endif
125+
PythonQtConv::registerStringViewTypes();
129126

130127
int objectPtrListId = qRegisterMetaType<QList<PythonQtObjectPtr> >("QList<PythonQtObjectPtr>");
131128
PythonQtConv::registerMetaTypeToPythonConverter(objectPtrListId, PythonQtConv::convertFromQListOfPythonQtObjectPtr);

src/PythonQtConversion.cpp

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@
4848
#include <climits>
4949
#include <limits>
5050

51+
#if QT_VERSION < 0x060000
52+
#include <QStringRef>
53+
54+
Q_DECLARE_METATYPE(QStringRef)
55+
56+
int PythonQtConv::stringRefTypeId = 0;
57+
#else
58+
#include <QStringView>
59+
#include <QAnyStringView>
60+
61+
int PythonQtConv::stringViewTypeId = 0;
62+
int PythonQtConv::anyStringViewTypeId = 0;
63+
#endif
64+
5165
QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
5266
QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
5367

@@ -633,19 +647,69 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
633647
// we have a exact enum type match:
634648
val = PyInt_AS_LONG(obj);
635649
ok = true;
636-
} else if (!strict) {
650+
}
651+
else if (!strict) {
637652
// we try to get any integer, when not being strict. If we are strict, integers are not wanted because
638653
// we want an integer overload to be taken first!
639654
val = (unsigned int)PyObjGetLongLong(obj, false, ok);
640655
}
641656
if (ok) {
642-
PythonQtArgumentFrame_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,frame, unsigned int, val, ptr);
657+
PythonQtArgumentFrame_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, unsigned int, val, ptr);
643658
return ptr;
644-
} else {
659+
}
660+
else {
645661
return nullptr;
646662
}
647663
}
648664

665+
// Handle QStringView et al, which need a reference to a persistent QString
666+
#if QT_VERSION < 0x060000
667+
if (info.typeId == stringRefTypeId) {
668+
QString str = PyObjGetString(obj, strict, ok);
669+
if (ok) {
670+
void* ptr2 = nullptr;
671+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
672+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
673+
QVariant::fromValue(QStringRef((const QString*)((QVariant*)ptr2)->constData())), ptr);
674+
ptr = (void*)((QVariant*)ptr)->constData();
675+
return ptr;
676+
}
677+
else {
678+
return nullptr;
679+
}
680+
}
681+
#else
682+
if (info.typeId == stringViewTypeId) {
683+
QString str = PyObjGetString(obj, strict, ok);
684+
if (ok) {
685+
void* ptr2 = nullptr;
686+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
687+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
688+
QVariant::fromValue(QStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
689+
ptr = (void*)((QVariant*)ptr)->constData();
690+
return ptr;
691+
}
692+
else {
693+
return nullptr;
694+
}
695+
}
696+
else if (info.typeId == anyStringViewTypeId) {
697+
// Handle QStringView et al, which need a reference to a persistent QString
698+
QString str = PyObjGetString(obj, strict, ok);
699+
if (ok) {
700+
void* ptr2 = nullptr;
701+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
702+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
703+
QVariant::fromValue(QAnyStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
704+
ptr = (void*)((QVariant*)ptr)->constData();
705+
return ptr;
706+
}
707+
else {
708+
return nullptr;
709+
}
710+
}
711+
#endif
712+
649713
if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
650714
// check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
651715
if (info.isQList && (info.innerNamePointerCount == 1)) {
@@ -1498,6 +1562,16 @@ PyObject* PythonQtConv::convertFromStringRef(const void* inObject, int /*metaTyp
14981562
{
14991563
return PythonQtConv::QStringToPyObject(((QStringRef*)inObject)->toString());
15001564
}
1565+
#else
1566+
PyObject* PythonQtConv::convertFromStringView(const void* inObject, int /*metaTypeId*/)
1567+
{
1568+
return PythonQtConv::QStringToPyObject(((QStringView*)inObject)->toString());
1569+
}
1570+
1571+
PyObject* PythonQtConv::convertFromAnyStringView(const void* inObject, int /*metaTypeId*/)
1572+
{
1573+
return PythonQtConv::QStringToPyObject(((QAnyStringView*)inObject)->toString());
1574+
}
15011575
#endif
15021576

15031577
QByteArray PythonQtConv::getCPPTypeName(PyObject* type)
@@ -1550,6 +1624,19 @@ bool PythonQtConv::isStringType(PyTypeObject* type)
15501624
#endif
15511625
}
15521626

1627+
void PythonQtConv::registerStringViewTypes()
1628+
{
1629+
#if QT_VERSION < 0x060000
1630+
stringRefTypeId = qRegisterMetaType<QStringRef>("QStringRef");
1631+
PythonQtConv::registerMetaTypeToPythonConverter(stringRefTypeId, PythonQtConv::convertFromStringRef);
1632+
#else
1633+
stringViewTypeId = qRegisterMetaType<QStringView>("QStringView");
1634+
PythonQtConv::registerMetaTypeToPythonConverter(stringViewTypeId, PythonQtConv::convertFromStringView);
1635+
anyStringViewTypeId = qRegisterMetaType<QAnyStringView>("QAnyStringView");
1636+
PythonQtConv::registerMetaTypeToPythonConverter(anyStringViewTypeId, PythonQtConv::convertFromAnyStringView);
1637+
#endif
1638+
}
1639+
15531640
PyObject* PythonQtConv::convertFromQListOfPythonQtObjectPtr(const void* inObject, int /*metaTypeId*/)
15541641
{
15551642
QList<PythonQtObjectPtr>& list = *((QList<PythonQtObjectPtr>*)inObject);

src/PythonQtConversion.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ class PYTHONQT_EXPORT PythonQtConv {
187187
static PyObject* convertFromQListOfPythonQtObjectPtr(const void* /* QList<PythonQtObjectPtr>* */ inObject, int /*metaTypeId*/);
188188
#if QT_VERSION < 0x060000
189189
static PyObject* convertFromStringRef(const void* inObject, int /*metaTypeId*/);
190+
#else
191+
static PyObject* convertFromStringView(const void* inObject, int /*metaTypeId*/);
192+
static PyObject* convertFromAnyStringView(const void* inObject, int /*metaTypeId*/);
190193
#endif
191194

192195
//! Returns the name of the equivalent CPP type (for signals and slots)
@@ -195,6 +198,9 @@ class PYTHONQT_EXPORT PythonQtConv {
195198
//! Returns if the given object is a string (or unicode string)
196199
static bool isStringType(PyTypeObject* type);
197200

201+
//! Register QStringView like types, that need to be handled specially
202+
static void registerStringViewTypes();
203+
198204
protected:
199205
static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
200206
static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
@@ -215,6 +221,12 @@ class PYTHONQT_EXPORT PythonQtConv {
215221
template <typename Map>
216222
static PyObject* mapToPython (const Map& m);
217223

224+
#if QT_VERSION < 0x060000
225+
static int stringRefTypeId;
226+
#else
227+
static int stringViewTypeId;
228+
static int anyStringViewTypeId;
229+
#endif
218230
};
219231

220232
template<class ListType, class T>

0 commit comments

Comments
 (0)