aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/PySide6/glue
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/PySide6/glue')
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp901
-rw-r--r--sources/pyside6/PySide6/glue/qtdatavisualization.cpp11
-rw-r--r--sources/pyside6/PySide6/glue/qtgraphs.cpp8
-rw-r--r--sources/pyside6/PySide6/glue/qtgui.cpp85
-rw-r--r--sources/pyside6/PySide6/glue/qtmultimedia.cpp6
-rw-r--r--sources/pyside6/PySide6/glue/qtnetwork.cpp86
-rw-r--r--sources/pyside6/PySide6/glue/qtnetworkauth.cpp43
-rw-r--r--sources/pyside6/PySide6/glue/qtpositioning.cpp14
-rw-r--r--sources/pyside6/PySide6/glue/qtqml.cpp26
-rw-r--r--sources/pyside6/PySide6/glue/qtquick.cpp21
-rw-r--r--sources/pyside6/PySide6/glue/qtquicktest.cpp50
-rw-r--r--sources/pyside6/PySide6/glue/qtstatemachine.cpp3
-rw-r--r--sources/pyside6/PySide6/glue/qtuitools.cpp42
-rw-r--r--sources/pyside6/PySide6/glue/qtwebenginecore.cpp68
-rw-r--r--sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp6
-rw-r--r--sources/pyside6/PySide6/glue/qtwidgets.cpp134
16 files changed, 1145 insertions, 359 deletions
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
index 0f4816bbb..0c206db72 100644
--- a/sources/pyside6/PySide6/glue/qtcore.cpp
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -11,6 +11,10 @@
#include "glue/core_snippets_p.h"
// @snippet include-pyside
+// @snippet core-snippets-p-h
+#include "glue/core_snippets_p.h"
+// @snippet core-snippets-p-h
+
// @snippet qarg_helper
// Helper for the Q_ARG/Q_RETURN_ARG functions, creating a meta type
@@ -56,6 +60,115 @@ QArgData qArgDataFromPyType(PyObject *t)
}
// @snippet qarg_helper
+// @snippet settings-value-helpers
+// Convert a QVariant to a desired primitive type
+static PyObject *convertToPrimitiveType(const QVariant &out, int metaTypeId)
+{
+ switch (metaTypeId) {
+ case QMetaType::QByteArray:
+ return PyBytes_FromString(out.toByteArray().constData());
+ case QMetaType::QString:
+ return PyUnicode_FromString(out.toByteArray().constData());
+ case QMetaType::Short:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::UShort:
+ case QMetaType::ULong:
+ case QMetaType::ULongLong:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ return PyLong_FromDouble(out.toFloat());
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::Float16:
+ return PyFloat_FromDouble(out.toFloat());
+ case QMetaType::Bool:
+ if (out.toBool()) {
+ Py_RETURN_TRUE;
+ }
+ Py_RETURN_FALSE;
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+// Helper for QSettings::value() to convert a value to the desired type
+static PyObject *settingsTypeCoercion(const QVariant &out, PyTypeObject *typeObj)
+{
+ if (typeObj == &PyList_Type) {
+ // Convert any string, etc, to a list of 1 element
+ if (auto *primitiveValue = convertToPrimitiveType(out, out.typeId())) {
+ PyObject *list = PyList_New(1);
+ PyList_SET_ITEM(list, 0, primitiveValue);
+ return list;
+ }
+
+ const QByteArray out_ba = out.toByteArray();
+ if (out_ba.isEmpty())
+ return PyList_New(0);
+
+ const QByteArrayList valuesList = out_ba.split(',');
+ const Py_ssize_t valuesSize = valuesList.size();
+ PyObject *list = PyList_New(valuesSize);
+ for (Py_ssize_t i = 0; i < valuesSize; ++i) {
+ PyObject *item = PyUnicode_FromString(valuesList.at(i).constData());
+ PyList_SET_ITEM(list, i, item);
+ }
+ return list;
+ }
+
+ if (typeObj == &PyBytes_Type)
+ return convertToPrimitiveType(out, QMetaType::QByteArray);
+ if (typeObj == &PyUnicode_Type)
+ return convertToPrimitiveType(out, QMetaType::QString);
+ if (typeObj == &PyLong_Type)
+ return convertToPrimitiveType(out, QMetaType::Int);
+ if (typeObj == &PyFloat_Type)
+ return convertToPrimitiveType(out, QMetaType::Double);
+ if (typeObj == &PyBool_Type)
+ return convertToPrimitiveType(out, QMetaType::Bool);
+
+ // TODO: PyDict_Type and PyTuple_Type
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid type parameter.\n"
+ "\tUse 'list', 'bytes', 'str', 'int', 'float', 'bool', "
+ "or a Qt-derived type");
+ return nullptr;
+}
+
+static bool isEquivalentSettingsType(PyTypeObject *typeObj, int metaTypeId)
+{
+ switch (metaTypeId) {
+ case QMetaType::QVariantList:
+ case QMetaType::QStringList:
+ return typeObj == &PyList_Type;
+ case QMetaType::QByteArray:
+ return typeObj == &PyBytes_Type;
+ case QMetaType::QString:
+ return typeObj == &PyUnicode_Type;
+ case QMetaType::Short:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::UShort:
+ case QMetaType::ULong:
+ case QMetaType::ULongLong:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ return typeObj == &PyLong_Type;
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::Float16:
+ return typeObj == &PyFloat_Type;
+ case QMetaType::Bool:
+ return typeObj == &PyBool_Type;
+ default:
+ break;
+ }
+ return false;
+}
+// @snippet settings-value-helpers
+
// @snippet qsettings-value
// If we enter the kwds, means that we have a defaultValue or
// at least a type.
@@ -76,61 +189,15 @@ if ((kwds && PyDict_Size(kwds) > 0) || numArgs > 1) {
PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3);
-if (typeObj && !Shiboken::ObjectType::checkType(typeObj)) {
- if (typeObj == &PyList_Type) {
- QByteArray out_ba = out.toByteArray();
- if (!out_ba.isEmpty()) {
- QByteArrayList valuesList = out_ba.split(',');
- const Py_ssize_t valuesSize = valuesList.size();
- if (valuesSize > 0) {
- PyObject *list = PyList_New(valuesSize);
- for (Py_ssize_t i = 0; i < valuesSize; ++i) {
- PyObject *item = PyUnicode_FromString(valuesList.at(i).constData());
- PyList_SET_ITEM(list, i, item);
- }
- %PYARG_0 = list;
-
- } else {
- %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
- }
- } else {
- %PYARG_0 = PyList_New(0);
- }
- } else if (typeObj == &PyBytes_Type) {
- QByteArray asByteArray = out.toByteArray();
- %PYARG_0 = PyBytes_FromString(asByteArray.constData());
- } else if (typeObj == &PyUnicode_Type) {
- QByteArray asByteArray = out.toByteArray();
- %PYARG_0 = PyUnicode_FromString(asByteArray.constData());
- } else if (typeObj == &PyLong_Type) {
- float asFloat = out.toFloat();
- pyResult = PyLong_FromDouble(asFloat);
- } else if (typeObj == &PyFloat_Type) {
- float asFloat = out.toFloat();
- %PYARG_0 = PyFloat_FromDouble(asFloat);
- } else if (typeObj == &PyBool_Type) {
- if (out.toBool()) {
- Py_INCREF(Py_True);
- %PYARG_0 = Py_True;
- } else {
- Py_INCREF(Py_False);
- %PYARG_0 = Py_False;
- }
+if (typeObj && !Shiboken::ObjectType::checkType(typeObj)
+ && !isEquivalentSettingsType(typeObj, out.typeId())) {
+ %PYARG_0 = settingsTypeCoercion(out, typeObj);
+} else {
+ if (out.isValid()) {
+ %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
} else {
- // TODO: PyDict_Type and PyTuple_Type
- PyErr_SetString(PyExc_TypeError,
- "Invalid type parameter.\n"
- "\tUse 'list', 'bytes', 'str', 'int', 'float', 'bool', "
- "or a Qt-derived type");
- return nullptr;
- }
-}
-else {
- if (!out.isValid()) {
Py_INCREF(Py_None);
%PYARG_0 = Py_None;
- } else {
- %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
}
}
@@ -141,11 +208,7 @@ else {
// @snippet metatype-from-type
// @snippet metatype-from-metatype-type
-Shiboken::AutoDecRef intArg;
-if (usingNewEnum())
- intArg.reset(PyObject_GetAttrString(%PYARG_1, "value"));
-else
- intArg.reset(PyObject_CallMethod(%PYARG_1, "__int__", nullptr));
+Shiboken::AutoDecRef intArg(PyObject_GetAttrString(%PYARG_1, "value"));
%0 = new %TYPE(PyLong_AsLong(intArg));
// @snippet metatype-from-metatype-type
@@ -167,7 +230,7 @@ static QVariant QVariant_convertToVariantMap(PyObject *map)
Py_ssize_t pos = 0;
Shiboken::AutoDecRef keys(PyDict_Keys(map));
if (!QVariant_isStringList(keys))
- return QVariant();
+ return {};
PyObject *key;
PyObject *value;
QMap<QString,QVariant> ret;
@@ -191,7 +254,7 @@ static QVariant QVariant_convertToVariantList(PyObject *list)
if (PySequence_Size(list) < 0) {
// clear the error if < 0 which means no length at all
PyErr_Clear();
- return QVariant();
+ return {};
}
QList<QVariant> lst;
@@ -204,6 +267,30 @@ static QVariant QVariant_convertToVariantList(PyObject *list)
}
return QVariant(lst);
}
+
+using SpecificConverter = Shiboken::Conversions::SpecificConverter;
+
+static std::optional<SpecificConverter> converterForQtType(const char *typeNameC)
+{
+ // Fix typedef "QGenericMatrix<3,3,float>" -> QMatrix3x3". The reverse
+ // conversion happens automatically in QMetaType::fromName() in
+ // QVariant_resolveMetaType().
+ QByteArrayView typeNameV(typeNameC);
+ if (typeNameV.startsWith("QGenericMatrix<") && typeNameV.endsWith(",float>")) {
+ QByteArray typeName = typeNameV.toByteArray();
+ typeName.remove(1, 7);
+ typeName.remove(7, 1); // '<'
+ typeName.chop(7);
+ typeName.replace(',', 'x');
+ SpecificConverter matrixConverter(typeName.constData());
+ if (matrixConverter)
+ return matrixConverter;
+ }
+ SpecificConverter converter(typeNameC);
+ if (converter)
+ return converter;
+ return std::nullopt;
+}
// @snippet qvariant-conversion
// @snippet qt-qabs
@@ -219,6 +306,18 @@ PySide::addPostRoutine(%1);
qAddPostRoutine(PySide::globalPostRoutineCallback);
// @snippet qt-qaddpostroutine
+// @snippet qcompress-buffer
+auto *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+QByteArray compressed = %FUNCTION_NAME(ptr, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](compressed);
+// @snippet qcompress-buffer
+
+// @snippet quncompress-buffer
+auto *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+QByteArray uncompressed = %FUNCTION_NAME(ptr, %2);
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](uncompressed);
+// @snippet quncompress-buffer
+
// @snippet qt-version
QList<QByteArray> version = QByteArray(qVersion()).split('.');
PyObject *pyQtVersion = PyTuple_New(3);
@@ -256,6 +355,12 @@ PyModule_AddStringConstant(module, "__version__", qVersion());
%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
// @snippet qobject-connect-4
+// @snippet qobject-connect-4-context
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnectCallback(%1, %2, %3, %PYARG_4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-4-context
+
// @snippet qobject-connect-5
// %FUNCTION_NAME() - disable generation of function call.
%RETURN_TYPE %0 = PySide::qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3);
@@ -312,10 +417,10 @@ PySide::Feature::init();
// @snippet qt-init-feature
// @snippet qt-pysideinit
-Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode");
-Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
-Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList");
-Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QString_IDX], "unicode");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QString_IDX], "str");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QtCore_QList_QVariant_IDX], "QVariantList");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QtCore_QMap_QString_QVariant_IDX], "QVariantMap");
PySide::registerInternalQtConf();
PySide::init(module);
@@ -365,8 +470,7 @@ if (%PYARG_0 == Py_None)
namespace PySide {
template<> inline Py_ssize_t hash(const QLine &l)
{
- const int v[4] = {l.x1(), l.y1(), l.x2(), l.y2()};
- return qHashRange(v, v + 4);
+ return qHashMulti(0, l.x1(), l.y1(), l.x2(), l.y2());
}
};
// @snippet qline-hash
@@ -438,31 +542,6 @@ if (!PyDateTimeAPI)
%PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000);
// @snippet qdatetime-topython
-// @snippet qpoint
-namespace PySide {
- template<> inline Py_ssize_t hash(const QPoint &v) {
- return qHash(qMakePair(v.x(), v.y()));
- }
-};
-// @snippet qpoint
-
-// @snippet qrect
-namespace PySide {
- template<> inline Py_ssize_t hash(const QRect &r) {
- const int v[4] = {r.x(), r.y(), r.width(), r.height()};
- return qHashRange(v, v + 4);
- }
-};
-// @snippet qrect
-
-// @snippet qsize
-namespace PySide {
- template<> inline Py_ssize_t hash(const QSize &v) {
- return qHash(qMakePair(v.width(), v.height()));
- }
-};
-// @snippet qsize
-
// @snippet qtime-topython
if (!PyDateTimeAPI)
PyDateTime_IMPORT;
@@ -536,32 +615,31 @@ const QString result = qObjectTr(reinterpret_cast<PyTypeObject *>(%PYSELF), %1,
%PYARG_0 = %CONVERTTOPYTHON[QString](result);
// @snippet qobject-tr
-// @snippet qobject-receivers
-// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife
-int ret = %CPPSELF.%FUNCTION_NAME(%1);
-if (ret > 0 && ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0)))
- ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF);
-
-%PYARG_0 = %CONVERTTOPYTHON[int](ret);
-// @snippet qobject-receivers
+// @snippet qobject-sender
+// Retrieve the sender from a dynamic property set by GlobalReceiverV2 in case of a
+// non-C++ slot (Python callback).
+auto *ret = %CPPSELF.%FUNCTION_NAME();
+if (ret == nullptr) {
+ auto senderV = %CPPSELF.property("_q_pyside_sender");
+ if (senderV.typeId() == QMetaType::QObjectStar)
+ ret = senderV.value<QObject *>();
+}
+%PYARG_0 = %CONVERTTOPYTHON[QObject*](ret);
+// @snippet qobject-sender
// @snippet qbytearray-mgetitem
-if (PepIndex_Check(_key)) {
+if (PyIndex_Check(_key)) {
const Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
- if (_i < 0 || _i >= %CPPSELF.size()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return nullptr;
- }
+ if (_i < 0 || _i >= %CPPSELF.size())
+ return PyErr_Format(PyExc_IndexError, "index out of bounds");
char res[2] = {%CPPSELF.at(_i), '\0'};
return PyBytes_FromStringAndSize(res, 1);
}
-if (PySlice_Check(_key) == 0) {
- PyErr_Format(PyExc_TypeError,
+if (PySlice_Check(_key) == 0)
+ return PyErr_Format(PyExc_TypeError,
"list indices must be integers or slices, not %.200s",
Py_TYPE(_key)->tp_name);
- return nullptr;
-}
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(_key, %CPPSELF.size(), &start, &stop, &step, &slicelength) < 0)
@@ -587,7 +665,8 @@ return %CONVERTTOPYTHON[QByteArray](ba);
// @snippet qbytearray-mgetitem
// @snippet qbytearray-msetitem
-if (PepIndex_Check(_key)) {
+// PYSIDE-2404: Usage of the `get()` function not necessary, the type exists.
+if (PyIndex_Check(_key)) {
Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
if (_i == -1 && PyErr_Occurred())
return -1;
@@ -611,7 +690,8 @@ if (PepIndex_Check(_key)) {
PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1");
return -1;
}
- } else if (Py_TYPE(_value) == reinterpret_cast<PyTypeObject *>(SbkPySide6_QtCoreTypes[SBK_QBYTEARRAY_IDX])) {
+ } else if (Py_TYPE(_value) == reinterpret_cast<PyTypeObject *>(
+ SbkPySide6_QtCoreTypeStructs[SBK_QByteArray_IDX].type)) {
if (PyObject_Length(_value) != 1) {
PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1");
return -1;
@@ -648,7 +728,7 @@ if (PySlice_GetIndicesEx(_key, %CPPSELF.size(), &start, &stop, &step, &sliceleng
Py_ssize_t value_length = 0;
if (_value != nullptr && _value != Py_None) {
if (!(PyBytes_Check(_value) || PyByteArray_Check(_value)
- || Py_TYPE(_value) == reinterpret_cast<PyTypeObject *>(SbkPySide6_QtCoreTypes[SBK_QBYTEARRAY_IDX]))) {
+ || Py_TYPE(_value) == SbkPySide6_QtCoreTypeStructs[SBK_QByteArray_IDX].type)) {
PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s",
Py_TYPE(_value)->tp_name);
return -1;
@@ -705,10 +785,10 @@ static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags
view->len = cppSelf->size();
view->readonly = 0;
view->itemsize = 1;
- view->format = const_cast<char *>("c");
+ view->format = (flags & PyBUF_FORMAT) == PyBUF_FORMAT ? const_cast<char *>("B") : nullptr;
view->ndim = 1;
view->shape = (flags & PyBUF_ND) == PyBUF_ND ? &(view->len) : nullptr;
- view->strides = &view->itemsize;
+ view->strides = (flags & PyBUF_STRIDES) == PyBUF_STRIDES ? &(view->itemsize) : nullptr;
view->suboffsets = nullptr;
view->internal = nullptr;
@@ -874,6 +954,13 @@ uchar *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1));
%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite);
// @snippet qfiledevice-map
+// @snippet qiodevice-bufferedread
+Py_ssize_t bufferLen;
+auto *data = reinterpret_cast<char*>(Shiboken::Buffer::getPointer(%PYARG_1, &bufferLen));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(data, PyLong_AsLongLong(%PYARG_2));
+return PyLong_FromLong(%0);
+// @snippet qiodevice-bufferedread
+
// @snippet qiodevice-readdata
QByteArray ba(1 + qsizetype(%2), char(0));
%CPPSELF.%FUNCTION_NAME(ba.data(), qint64(%2));
@@ -921,62 +1008,126 @@ auto *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1, &si
%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
// @snippet qtranslator-load
-// @snippet qtimer-singleshot-1
-// %FUNCTION_NAME() - disable generation of c++ function call
-(void) %2; // remove warning about unused variable
-Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
-auto *timerType = Shiboken::SbkType<QTimer>();
-auto *pyTimer = timerType->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
-timerType->tp_init(pyTimer, emptyTuple, nullptr);
-
-auto timer = %CONVERTTOCPP[QTimer *](pyTimer);
-Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer, "connect", "OsOs",
- pyTimer,
- SIGNAL(timeout()),
- %PYARG_2,
- %3)
-);
-Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
-Py_XDECREF(pyTimer);
-timer->setSingleShot(true);
-timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater);
-timer->start(%1);
-// @snippet qtimer-singleshot-1
-
-// @snippet qtimer-singleshot-2
-// %FUNCTION_NAME() - disable generation of c++ function call
+// @snippet qtimer-singleshot-functorclass
+struct QSingleShotTimerFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()();
+};
+
+void QSingleShotTimerFunctor::operator()()
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ if (Shiboken::Errors::occurred())
+ Shiboken::Errors::storeErrorOrPrint();
+ release(); // single shot
+}
+// @snippet qtimer-singleshot-functorclass
+
+// @snippet qtimer-singleshot-direct-mapping
Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
-auto *timerType = Shiboken::SbkType<QTimer>();
-auto *pyTimer = timerType->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
-timerType->tp_init(pyTimer, emptyTuple, nullptr);
-QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
-timer->setSingleShot(true);
-
-if (PyObject_TypeCheck(%2, PySideSignalInstance_TypeF())) {
- PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%2);
- Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
- Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer, "connect", "OsOO",
- pyTimer,
- SIGNAL(timeout()),
- PySide::Signal::getObject(signalInstance),
- signalSignature.object())
- );
+%CPPSELF.%FUNCTION_NAME(%1, %2, %3);
+// @snippet qtimer-singleshot-direct-mapping
+
+// @snippet qtimer-singleshot-functor
+auto msec = %1;
+if (msec == 0) {
+ if (PyObject_TypeCheck(%2, PySideSignalInstance_TypeF())) {
+ auto *signal = %PYARG_2;
+ auto cppCallback = [signal]()
+ {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef ret(PyObject_CallMethod(signal, "emit", "()"));
+ Py_DECREF(signal);
+ };
+
+ Py_INCREF(signal);
+ %CPPSELF.%FUNCTION_NAME(msec, cppCallback);
+ } else {
+ %CPPSELF.%FUNCTION_NAME(msec, QSingleShotTimerFunctor(%PYARG_2));
+ }
+} else {
+ // %FUNCTION_NAME() - disable generation of c++ function call
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *timerType = Shiboken::SbkType<QTimer>();
+ auto newFunc = reinterpret_cast<newfunc>(PepType_GetSlot(timerType, Py_tp_new));
+ auto initFunc = reinterpret_cast<initproc>(PepType_GetSlot(timerType, Py_tp_init));
+ auto *pyTimer = newFunc(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
+ initFunc(pyTimer, emptyTuple, nullptr);
+
+ QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+ timer->setSingleShot(true);
+
+ if (PyObject_TypeCheck(%2, PySideSignalInstance_TypeF())) {
+ PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%2);
+ Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsOO",
+ pyTimer,
+ SIGNAL(timeout()),
+ PySide::Signal::getObject(signalInstance),
+ signalSignature.object())
+ );
+ } else {
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsO",
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2)
+ );
+ }
+
+ timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
+ Py_XDECREF(pyTimer);
+ timer->start(msec);
+}
+// @snippet qtimer-singleshot-functor
+
+// @snippet qtimer-singleshot-functor-context
+auto msec = %1;
+if (msec == 0) {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *callable = %PYARG_3;
+ auto cppCallback = [callable]()
+ {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+ };
+
+ Py_INCREF(callable);
+ %CPPSELF.%FUNCTION_NAME(msec, %2, cppCallback);
} else {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *timerType = Shiboken::SbkType<QTimer>();
+ auto newFunc = reinterpret_cast<newfunc>(PepType_GetSlot(timerType, Py_tp_new));
+ auto initFunc = reinterpret_cast<initproc>(PepType_GetSlot(timerType, Py_tp_init));
+ auto *pyTimer = newFunc(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
+ initFunc(pyTimer, emptyTuple, nullptr);
+
+ QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+ timer->setSingleShot(true);
+
Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer, "connect", "OsO",
+ PyObject_CallMethod(pyTimer, "connect", "OsOO",
pyTimer,
SIGNAL(timeout()),
- %PYARG_2)
+ %PYARG_2,
+ %PYARG_3)
);
-}
-timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
-Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
-Py_XDECREF(pyTimer);
-timer->start(%1);
-// @snippet qtimer-singleshot-2
+ timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
+ Py_XDECREF(pyTimer);
+ timer->start(msec);
+}
+// @snippet qtimer-singleshot-functor-context
// @snippet qprocess-startdetached
qint64 pid;
@@ -1042,6 +1193,16 @@ if (result == -1) {
}
// @snippet qdatastream-readrawdata
+// @snippet qdatastream-writerawdata-pybuffer
+int r = 0;
+Py_ssize_t bufferLen;
+auto *data = reinterpret_cast<const char*>(Shiboken::Buffer::getPointer(%PYARG_1, &bufferLen));
+Py_BEGIN_ALLOW_THREADS
+r = %CPPSELF.%FUNCTION_NAME(data, bufferLen);
+Py_END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](r);
+// @snippet qdatastream-writerawdata-pybuffer
+
// @snippet qdatastream-writerawdata
int r = 0;
Py_BEGIN_ALLOW_THREADS
@@ -1180,7 +1341,7 @@ Py_END_ALLOW_THREADS
if (atexit.isNull()) {
qWarning("Module atexit not found for registering __moduleShutdown");
PyErr_Clear();
- }else{
+ } else {
regFunc.reset(PyObject_GetAttrString(atexit, "register"));
if (regFunc.isNull()) {
qWarning("Function atexit.register not found for registering __moduleShutdown");
@@ -1318,7 +1479,7 @@ auto res = (*%CPPSELF) + cppArg0;
// @snippet conversion-pystring-char
char c = %CONVERTTOCPP[char](%in);
-%out = %OUTTYPE(c);
+%out = %OUTTYPE(static_cast<unsigned short>(c));
// @snippet conversion-pystring-char
// @snippet conversion-pyint
@@ -1352,15 +1513,23 @@ double in = %CONVERTTOCPP[double](%in);
// @snippet conversion-sbkobject
// a class supported by QVariant?
const QMetaType metaType = QVariant_resolveMetaType(Py_TYPE(%in));
+bool ok = false;
if (metaType.isValid()) {
QVariant var(metaType);
- Shiboken::Conversions::SpecificConverter converter(metaType.name());
- converter.toCpp(pyIn, var.data());
- %out = var;
-} else {
- // If the type was not encountered, return a default PyObjectWrapper
- %out = QVariant::fromValue(PySide::PyObjectWrapper(%in));
+ auto converterO = converterForQtType(metaType.name());
+ ok = converterO.has_value();
+ if (ok) {
+ converterO.value().toCpp(pyIn, var.data());
+ %out = var;
+ } else {
+ qWarning("%s: Cannot find a converter for \"%s\".",
+ __FUNCTION__, metaType.name());
+ }
}
+
+// If the type was not encountered, return a default PyObjectWrapper
+if (!ok)
+ %out = QVariant::fromValue(PySide::PyObjectWrapper(%in));
// @snippet conversion-sbkobject
// @snippet conversion-pydict
@@ -1446,10 +1615,40 @@ return PyLong_FromUnsignedLong(%in);
#endif
// @snippet return-pylong-quintptr
+// @snippet return-qfunctionpointer-pylong
+return PyLong_FromVoidPtr(reinterpret_cast<void *>(%in));
+// @snippet return-qfunctionpointer-pylong
+
+// @snippet conversion-pylong-qfunctionpointer
+%out = reinterpret_cast<QFunctionPointer>(PyLong_AsVoidPtr(%in));
+// @snippet conversion-pylong-qfunctionpointer
+
// @snippet return-pyunicode
return PySide::qStringToPyUnicode(%in);
// @snippet return-pyunicode
+// @snippet return-pyunicode-from-qlatin1string
+#ifdef Py_LIMITED_API
+return PySide::qStringToPyUnicode(QString::fromLatin1(%in));
+#else
+return PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, %in.constData(), %in.size());
+#endif
+// @snippet return-pyunicode-from-qlatin1string
+
+// @snippet qlatin1string-check
+static bool qLatin1StringCheck(PyObject *o)
+{
+ return PyUnicode_CheckExact(o) != 0
+ && _PepUnicode_KIND(o) == PepUnicode_1BYTE_KIND;
+}
+// @snippet qlatin1string-check
+
+// @snippet conversion-pystring-qlatin1string
+const char *data = reinterpret_cast<const char *>(_PepUnicode_DATA(%in));
+const Py_ssize_t len = PyUnicode_GetLength(%in);
+%out = QLatin1String(data, len);
+// @snippet conversion-pystring-qlatin1string
+
// @snippet return-pyunicode-from-qanystringview
return PySide::qStringToPyUnicode(%in.toString());
// @snippet return-pyunicode-from-qanystringview
@@ -1488,11 +1687,10 @@ default:
break;
}
-Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName());
-if (converter) {
- void *ptr = cppInRef.data();
- return converter.toPython(ptr);
-}
+auto converterO = converterForQtType(cppInRef.typeName());
+if (converterO.has_value())
+ return converterO.value().toPython(cppInRef.data());
+
PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName());
return 0;
// @snippet return-qvariant
@@ -1509,7 +1707,6 @@ return %CONVERTTOPYTHON[QVariant](ret);
// @snippet qthread_pthread_cleanup
#ifdef Q_OS_UNIX
-# include <stdio.h>
# include <pthread.h>
static void qthread_pthread_cleanup(void *arg)
{
@@ -1536,13 +1733,17 @@ pthread_cleanup_pop(0);
// @snippet qthread_pthread_cleanup_uninstall
// @snippet qlibraryinfo_build
-#if defined(Py_LIMITED_API)
-auto suffix = PyUnicode_FromString(" [limited API]");
auto oldResult = pyResult;
-pyResult = PyUnicode_Concat(pyResult, suffix);
-Py_DECREF(oldResult);
-Py_DECREF(suffix);
+const auto version = _PepRuntimeVersion();
+pyResult = PyUnicode_FromFormat(
+#ifdef Py_LIMITED_API
+ "%U [Python limited API %d.%d.%d]",
+#else
+ "%U [Python %d.%d.%d]",
#endif
+ oldResult, (version >> 16) & 0xFF,
+ (version >> 8) & 0xFF, version & 0xFF);
+Py_DECREF(oldResult);
// @snippet qlibraryinfo_build
// @snippet qsharedmemory_data_readonly
@@ -1603,8 +1804,9 @@ if (dataChar == nullptr) {
// @snippet qdatastream-read-bytes
// @snippet qloggingcategory_to_cpp
+// PYSIDE-2404: Usage of the `get()` function not necessary, the type exists.
QLoggingCategory *category{nullptr};
- Shiboken::Conversions::pythonToCppPointer(SbkPySide6_QtCoreTypes[SBK_QLOGGINGCATEGORY_IDX],
+ Shiboken::Conversions::pythonToCppPointer(SbkPySide6_QtCoreTypeStructs[SBK_QLoggingCategory_IDX].type,
pyArgs[0], &(category));
// @snippet qloggingcategory_to_cpp
@@ -1654,90 +1856,114 @@ QtCoreHelper::QGenericReturnArgumentHolder result(qArgData.metaType, qArgData.da
%PYARG_0 = %CONVERTTOPYTHON[QtCoreHelper::QGenericReturnArgumentHolder](result);
// @snippet q_return_arg
-// invokeMethod(QObject *,const char *, QGenericArgument a0, a1, a2 )
-// @snippet qmetaobject-invokemethod-arg
-PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
-const bool result = %CPPSELF.invokeMethod(%1, %2, %3, %4, %5);
-PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
-%PYARG_0 = %CONVERTTOPYTHON[bool](result);
-// @snippet qmetaobject-invokemethod-arg
+// @snippet qmetamethod-invoke-helpers
+static InvokeMetaMethodFunc
+ createInvokeMetaMethodFunc(const QMetaMethod &method, QObject *object,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [&method, object, type](QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return method.invoke(object, type, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
-// invokeMethod(QObject *,const char *,Qt::ConnectionType, QGenericArgument a0, a1, a2 )
-// @snippet qmetaobject-invokemethod-conn-type-arg
-PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
-const bool result = %CPPSELF.invokeMethod(%1, %2, %3, %4, %5, %6);
-PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
-%PYARG_0 = %CONVERTTOPYTHON[bool](result);
-// @snippet qmetaobject-invokemethod-conn-type-arg
+static InvokeMetaMethodFuncWithReturn
+ createInvokeMetaMethodFuncWithReturn(const QMetaMethod &method, QObject *object,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [&method, object, type](QGenericReturnArgument r,
+ QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return method.invoke(object, type, r, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
+// @snippet qmetamethod-invoke-helpers
-// @snippet qmetaobject-invokemethod-helpers
-static PyObject *invokeMethodHelper(QObject *obj, const char *member, Qt::ConnectionType type,
- const QtCoreHelper::QGenericReturnArgumentHolder &returnArg,
- const QtCoreHelper::QGenericArgumentHolder &v1,
- const QtCoreHelper::QGenericArgumentHolder &v2,
- const QtCoreHelper::QGenericArgumentHolder &v3)
+// @snippet qmetamethod-invoke-conn-type-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(*%CPPSELF, %1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
+// @snippet qmetamethod-invoke-conn-type-return-arg
+// @snippet qmetamethod-invoke-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(*%CPPSELF, %1),
+ %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetamethod-invoke-return-arg
+
+// @snippet qmetamethod-invoke-conn-type
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(*%CPPSELF, %1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetamethod-invoke-conn-type
+
+// @snippet qmetamethod-invoke
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(*%CPPSELF, %1),
+ %2, %3, %4, %5, %6, %7, %8, %9, %10, %11);
+// @snippet qmetamethod-invoke
+
+// @snippet qmetaobject-invokemethod-helpers
+static InvokeMetaMethodFunc
+ createInvokeMetaMethodFunc(QObject *object, const char *methodName,
+ Qt::ConnectionType type = Qt::AutoConnection)
{
- PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
- const bool callResult = QMetaObject::invokeMethod(obj, member, type,
- returnArg, v1, v2, v3);
- PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
- if (!callResult) {
- PyErr_Format(PyExc_RuntimeError, "QMetaObject::invokeMethod(): Invocation of %s::%s() failed.",
- obj->metaObject()->className(), member);
- return nullptr;
- }
+ return [object, methodName, type](QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return QMetaObject::invokeMethod(object, methodName, type,
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
- PyObject *result = nullptr;
- const void *retData = returnArg.data();
- const QMetaType metaType = returnArg.metaType();
- switch (metaType.id()) {
- case QMetaType::Bool:
- result = *reinterpret_cast<const bool *>(retData) ? Py_True : Py_False;
- Py_INCREF(result);
- break;
- case QMetaType::Int:
- result = PyLong_FromLong(*reinterpret_cast<const int *>(retData));
- break;
- case QMetaType::Double:
- result = PyFloat_FromDouble(*reinterpret_cast<const double *>(retData));
- break;
- case QMetaType::QString:
- result = PySide::qStringToPyUnicode(*reinterpret_cast<const QString *>(retData));
- break;
- default: {
- Shiboken::Conversions::SpecificConverter converter(metaType.name());
- const auto type = converter.conversionType();
- if (type == Shiboken::Conversions::SpecificConverter::InvalidConversion) {
- PyErr_Format(PyExc_RuntimeError, "%s: Unable to find converter for \"%s\".",
- __FUNCTION__, metaType.name());
- return nullptr;
- }
- result = converter.toPython(retData);
- }
- }
- return result;
+static InvokeMetaMethodFuncWithReturn
+ createInvokeMetaMethodFuncWithReturn(QObject *object, const char *methodName,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [object, methodName, type](QGenericReturnArgument r,
+ QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return QMetaObject::invokeMethod(object, methodName, type,
+ r, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
}
// @snippet qmetaobject-invokemethod-helpers
+// invokeMethod(QObject *,const char *, QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-arg
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(%1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetaobject-invokemethod-arg
+
+// invokeMethod(QObject *,const char *,Qt::ConnectionType, QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-conn-type-arg
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(%1, %2, %3),
+ %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
+// @snippet qmetaobject-invokemethod-conn-type-arg
+
// invokeMethod(QObject *,const char *, Qt::ConnectionType, QGenericReturnArgument,QGenericArgument a0, a1, a2 )
// @snippet qmetaobject-invokemethod-conn-type-return-arg
-%PYARG_0 = invokeMethodHelper(%1, %2, %3, %4, %5, %6, %7);
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(%1, %2, %3),
+ %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14);
// @snippet qmetaobject-invokemethod-conn-type-return-arg
// invokeMethod(QObject *,const char *, QGenericReturnArgument,QGenericArgument a0, a1, a2 )
// @snippet qmetaobject-invokemethod-return-arg
-%PYARG_0 = invokeMethodHelper(%1, %2, Qt::AutoConnection, %3, %4, %5, %6);
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(%1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
// @snippet qmetaobject-invokemethod-return-arg
-// @snippet qabstractitemmodel_data
-::QVariant %0;
-if (Shiboken::Enum::check(%PYARG_0))
- %0 = QVariant(int(Shiboken::Enum::getValue(%PYARG_0)));
-else
- pythonToCpp(pyResult, &cppResult);
-// @snippet qabstractitemmodel_data
-
// @snippet keycombination-from-keycombination
cptr = new ::%TYPE(%1);
// @snippet keycombination-from-keycombination
@@ -1745,3 +1971,180 @@ cptr = new ::%TYPE(%1);
// @snippet keycombination-from-modifier
cptr = new ::%TYPE(%1, %2);
// @snippet keycombination-from-modifier
+
+// @snippet qmetamethod-from-signal
+auto *signalInst = reinterpret_cast<PySideSignalInstance *>(%PYARG_1);
+const auto data = PySide::Signal::getEmitterData(signalInst);
+const auto result = data.methodIndex != -1
+ ? data.emitter->metaObject()->method(data.methodIndex)
+ : QMetaMethod{};
+%PYARG_0 = %CONVERTTOPYTHON[QMetaMethod](result);
+// @snippet qmetamethod-from-signal
+
+// @snippet qrunnable_create
+auto callable = %PYARG_1;
+auto callback = [callable]() -> void
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 1 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, nullptr));
+ Py_DECREF(callable);
+};
+Py_INCREF(callable);
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(callback);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qrunnable_create
+
+// @snippet qlocale_system
+// For darwin systems, QLocale::system() involves looking at the Info.plist of the application
+// bundle to detect the system localization. In the case of Qt for Python, the application bundle
+// is the used Python framework. To enable retreival of localized string, the property list key
+// CFBunldeAllowMixedLocalizations should be set to True inside the Info.plist file. Otherwise,
+// CFBundleDevelopmentRegion will be used to find the language preference of the user, which in the
+// case of Python is always english.
+// This is a hack until CFBunldeAllowMixedLocalizations will be set in the Python framework
+// installation in darwin systems.
+// Upstream issue in CPython: https://github.com/python/cpython/issues/108269
+#ifdef Q_OS_DARWIN
+ Shiboken::AutoDecRef locale(PyImport_ImportModule("locale"));
+ Shiboken::AutoDecRef getLocale(PyObject_GetAttrString(locale, "getlocale"));
+ Shiboken::AutoDecRef systemLocale(PyObject_CallObject(getLocale, nullptr));
+ PyObject* localeCode = PyTuple_GetItem(systemLocale, 0);
+ %RETURN_TYPE %0;
+ if (localeCode != Py_None) {
+ QString localeCodeStr = PySide::pyStringToQString(localeCode);
+ %0 = QLocale(localeCodeStr);
+ } else {
+ // The default locale is 'C' locale as mentioned in
+ // https://docs.python.org/3/library/locale.html
+ %0 = ::QLocale::c();
+ }
+#else
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
+#endif
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qlocale_system
+
+// @snippet qcoreapplication-requestpermission
+auto permission = %1;
+auto callable = %PYARG_3;
+
+// check if callable
+if (!PyCallable_Check(callable)) {
+ qWarning("Functor of %FUNCTION_NAME is not a callable");
+ return {};
+}
+
+// find the number of arguments of callable. It should either be empy or accept a QPermission
+// object
+int count = 0;
+PyObject* fc = nullptr;
+bool classMethod = false;
+Shiboken::AutoDecRef func_ob(PyObject_GetAttr(callable, Shiboken::PyMagicName::func()));
+
+if (func_ob.isNull() && PyObject_HasAttr(callable, Shiboken::PyMagicName::code())) {
+ // variable `callable` is a function
+ fc = PyObject_GetAttr(callable, Shiboken::PyMagicName::code());
+} else {
+ // variable `callable` is a class method
+ fc = PyObject_GetAttr(func_ob, Shiboken::PyMagicName::code());
+ classMethod = true;
+}
+
+if (fc) {
+ PyObject* ac = PyObject_GetAttrString(fc, "co_argcount");
+ if (ac) {
+ count = PyLong_AsLong(ac);
+ Py_DECREF(ac);
+ }
+ Py_DECREF(fc);
+}
+
+if ((classMethod && (count > 2)) || (!classMethod && (count > 1))) {
+ qWarning("Functor of %FUNCTION_NAME must either have QPermission object as argument or none."
+ "The QPermission object store the result of requestPermission()");
+ return {};
+}
+
+bool arg_qpermission = (classMethod && (count == 2)) || (!classMethod && (count == 1));
+
+auto callback = [callable, count, arg_qpermission](const QPermission &permission) -> void
+{
+ Shiboken::GilState state;
+ if (arg_qpermission) {
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist.object(), 0, %CONVERTTOPYTHON[QPermission](permission));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ } else {
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, nullptr));
+ }
+ Py_DECREF(callable);
+};
+Py_INCREF(callable);
+
+Py_BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(permission, %2, callback);
+Py_END_ALLOW_THREADS
+// @snippet qcoreapplication-requestpermission
+
+// @snippet qlockfile-getlockinfo
+qint64 pid{};
+QString hostname, appname;
+%CPPSELF.%FUNCTION_NAME(&pid, &hostname, &appname);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[qint64](pid));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](hostname));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[QString](appname));
+// @snippet qlockfile-getlockinfo
+
+// @snippet darwin_permission_plugin
+#ifdef Q_OS_DARWIN
+#include<QtCore/qplugin.h>
+// register the static plugin and setup its metadata
+Q_IMPORT_PLUGIN(QDarwinCameraPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinMicrophonePermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinBluetoothPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinContactsPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinCalendarPermissionPlugin)
+#endif
+// @snippet darwin_permission_plugin
+
+// @snippet qt-modifier
+PyObject *_inputDict = PyDict_New();
+// Note: The builtins line is no longer needed since Python 3.10. Undocumented!
+PyDict_SetItemString(_inputDict, "__builtins__", PyEval_GetBuiltins());
+PyDict_SetItemString(_inputDict, "QtCore", module);
+PyDict_SetItemString(_inputDict, "Qt", reinterpret_cast<PyObject *>(pyType));
+// Explicitly not dereferencing the result.
+PyRun_String(R"PY(if True:
+ from enum import Flag
+ from textwrap import dedent
+ from warnings import warn
+ # QtCore and Qt come as globals.
+
+ def func_or(self, other):
+ if isinstance(self, Flag) and isinstance(other, Flag):
+ # this is normal or-ing flags together
+ return Qt.KeyboardModifier(self.value | other.value)
+ return QtCore.QKeyCombination(self, other)
+
+ def func_add(self, other):
+ warn(dedent(f"""
+ The "+" operator is deprecated in Qt For Python 6.0 .
+ Please use "|" instead."""), stacklevel=2)
+ return func_or(self, other)
+
+ Qt.KeyboardModifier.__or__ = func_or
+ Qt.KeyboardModifier.__ror__ = func_or
+ Qt.Modifier.__or__ = func_or
+ Qt.Modifier.__ror__ = func_or
+ Qt.KeyboardModifier.__add__ = func_add
+ Qt.KeyboardModifier.__radd__ = func_add
+ Qt.Modifier.__add__ = func_add
+ Qt.Modifier.__radd__ = func_add
+
+)PY", Py_file_input, _inputDict, _inputDict);
+// @snippet qt-modifier
diff --git a/sources/pyside6/PySide6/glue/qtdatavisualization.cpp b/sources/pyside6/PySide6/glue/qtdatavisualization.cpp
index 049f9accc..3a179cb17 100644
--- a/sources/pyside6/PySide6/glue/qtdatavisualization.cpp
+++ b/sources/pyside6/PySide6/glue/qtdatavisualization.cpp
@@ -41,12 +41,21 @@ using ListType = decltype(%2);
using ListType = decltype(%2);
%CPPSELF.setRow(%1, new ListType(%2), %3);
// @snippet dataproxy-setrow-string
-//
+
// @snippet dataproxy-resetarray
using ListType = decltype(%1);
%CPPSELF.resetArray(new ListType(%1));
// @snippet dataproxy-resetarray
+// @snippet dataproxy-resetarray2
+using ListType = decltype(%1);
+%CPPSELF.resetArray(new ListType(%1), %2, %3);
+// @snippet dataproxy-resetarray2
+
+// @snippet scatterdataproxy-resetarray
+%CPPSELF.resetArray(new QScatterDataArray(*%1));
+// @snippet scatterdataproxy-resetarray
+
// @snippet qsurfacedataproxy-resetarraynp
auto *data = QtDataVisualizationHelper::surfaceDataFromNp(%1, %2, %3, %4, %5);
// %CPPSELF.%FUNCTION_NAME
diff --git a/sources/pyside6/PySide6/glue/qtgraphs.cpp b/sources/pyside6/PySide6/glue/qtgraphs.cpp
new file mode 100644
index 000000000..b5a5db799
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtgraphs.cpp
@@ -0,0 +1,8 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet graphs-qsurfacedataproxy-resetarraynp
+auto data = QtGraphsHelper::surfaceDataFromNp(%1, %2, %3, %4, %5);
+// %CPPSELF.%FUNCTION_NAME
+%CPPSELF.resetArray(data);
+// @snippet graphs-qsurfacedataproxy-resetarraynp
diff --git a/sources/pyside6/PySide6/glue/qtgui.cpp b/sources/pyside6/PySide6/glue/qtgui.cpp
index d610933ba..5c860a2bf 100644
--- a/sources/pyside6/PySide6/glue/qtgui.cpp
+++ b/sources/pyside6/PySide6/glue/qtgui.cpp
@@ -6,7 +6,9 @@
********************************************************************/
// @snippet gui-declarations
+QT_BEGIN_NAMESPACE
void qt_set_sequence_auto_mnemonic(bool);
+QT_END_NAMESPACE
// @snippet gui-declarations
// @snippet qaccessible-pysidefactory
@@ -313,10 +315,7 @@ if (_i < 0 || _i >= %CPPSELF.count()) {
return 0;
}
QKeyCombination item = (*%CPPSELF)[_i];
-if (usingNewEnum())
- return %CONVERTTOPYTHON[QKeyCombination](item);
-auto combined = item.toCombined();
-return %CONVERTTOPYTHON[int](combined);
+return %CONVERTTOPYTHON[QKeyCombination](item);
// @snippet qkeysequence-getitem
// @snippet qkeysequence-repr
@@ -374,6 +373,16 @@ const auto path = PySide::pyPathToQString(%PYARG_1);
%CPPSELF->addPixmap(path);
// @snippet qicon-addpixmap
+// @snippet qclipboard-setpixmap
+const auto path = PySide::pyPathToQString(%PYARG_1);
+%CPPSELF->setPixmap(QPixmap(path));
+// @snippet qclipboard-setpixmap
+
+// @snippet qclipboard-setimage
+const auto path = PySide::pyPathToQString(%PYARG_1);
+%CPPSELF->setImage(QImage(path));
+// @snippet qclipboard-setimage
+
// @snippet qimage-decref-image-data
static void imageDecrefDataHandler(void *data)
{
@@ -774,12 +783,45 @@ auto *cppResult = new QtGuiHelper::QOverrideCursorGuard();
Shiboken::Object::getOwnership(%PYARG_0); // Ensure the guard is removed
// @snippet qguiapplication-setoverridecursor
+// @snippet qguiapplication-nativeInterface
+bool hasNativeApp = false;
+#if QT_CONFIG(xcb)
+if (auto *x11App = %CPPSELF.nativeInterface<QNativeInterface::QX11Application>()) {
+ hasNativeApp = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QNativeInterface::QX11Application*](x11App);
+}
+#endif
+if (!hasNativeApp) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qguiapplication-nativeInterface
+
// @snippet qscreen-grabWindow
WId id = %1;
%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id, %2, %3, %4, %5);
%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
// @snippet qscreen-grabWindow
+// @snippet qscreen-nativeInterface
+bool hasNativeScreen = false;
+#ifdef Q_OS_WIN
+if (auto *winScreen = %CPPSELF.nativeInterface<QNativeInterface::QWindowsScreen>()) {
+ hasNativeScreen = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QNativeInterface::QWindowsScreen*](winScreen);
+}
+#endif
+if (!hasNativeScreen) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qscreen-nativeInterface
+
+// @snippet qx11application-resource-ptr
+ auto *resource = %CPPSELF.%FUNCTION_NAME();
+%PYARG_0 = PyLong_FromVoidPtr(resource);
+// @snippet qx11application-resource-ptr
+
// @snippet qwindow-fromWinId
WId id = %1;
%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id);
@@ -847,20 +889,47 @@ else
%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
// @snippet qdrag-exec-arg2
+// @snippet qquaternion-getaxisandangle-vector3d-float
+QVector3D outVec{};
+float angle{};
+%CPPSELF.%FUNCTION_NAME(&outVec, &angle);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QVector3D](outVec));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[float](angle));
+// @snippet qquaternion-getaxisandangle-vector3d-float
+
+// @snippet qquaternion-geteulerangles
+float pitch{}, yaw{}, roll{};
+%CPPSELF.%FUNCTION_NAME(&pitch, &yaw, &roll);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[float](pitch));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[float](yaw));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[float](roll));
+// @snippet qquaternion-geteulerangles
+
// @snippet qregion-len
return %CPPSELF.rectCount();
// @snippet qregion-len
// @snippet qregion-getitem
-if (_i < 0 || _i >= %CPPSELF.rectCount()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return nullptr;
-}
+if (_i < 0 || _i >= %CPPSELF.rectCount())
+ return PyErr_Format(PyExc_IndexError, "index out of bounds");
const QRect cppResult = *(%CPPSELF.cbegin() + _i);
return %CONVERTTOPYTHON[QRect](cppResult);
// @snippet qregion-getitem
+// Some RHI functions take a std::initializer_list<>. Add functions
+// to convert from list.
+
+// @snippet qrhi-initializer-list
+%CPPSELF.%FUNCTION_NAME(%1.cbegin(), %1.cend());
+// @snippet qrhi-initializer-list
+
+// @snippet qrhi-commandbuffer-setvertexinput
+%CPPSELF.%FUNCTION_NAME(%1, %2.size(), %2.constData(), %3, %4, %5);
+// @snippet qrhi-commandbuffer-setvertexinput
+
/*********************************************************************
* CONVERSIONS
********************************************************************/
diff --git a/sources/pyside6/PySide6/glue/qtmultimedia.cpp b/sources/pyside6/PySide6/glue/qtmultimedia.cpp
index 3d46619fd..ac8434b97 100644
--- a/sources/pyside6/PySide6/glue/qtmultimedia.cpp
+++ b/sources/pyside6/PySide6/glue/qtmultimedia.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// @snippet qvideoframe-bits
+#include "object.h"
%BEGIN_ALLOW_THREADS
%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1);
%END_ALLOW_THREADS
@@ -20,3 +21,8 @@ const unsigned char *data = %CPPSELF.%FUNCTION_NAME<unsigned char>();
const auto size = %CPPSELF.byteCount();
%PYARG_0 = Shiboken::Buffer::newObject(data, size);
// @snippet qaudiobuffer-const-data
+
+// @snippet qtaudio-namespace-compatibility-alias
+Py_INCREF(pyType);
+PyModule_AddObject(module, "QtAudio", reinterpret_cast<PyObject *>(pyType));
+// @snippet qtaudio-namespace-compatibility-alias
diff --git a/sources/pyside6/PySide6/glue/qtnetwork.cpp b/sources/pyside6/PySide6/glue/qtnetwork.cpp
index f00780b40..f635f4671 100644
--- a/sources/pyside6/PySide6/glue/qtnetwork.cpp
+++ b/sources/pyside6/PySide6/glue/qtnetwork.cpp
@@ -15,20 +15,28 @@ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QHostAddress](ha));
PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[quint16](port));
// @snippet qudpsocket-readdatagram
-// @snippet qhostinfo-lookuphost-callable
-auto *callable = %PYARG_2;
-auto cppCallback = [callable](const QHostInfo &hostInfo)
+// @snippet qhostinfo-lookuphost-functor
+struct QHostInfoFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(const QHostInfo &hostInfo);
+};
+
+void QHostInfoFunctor::operator()(const QHostInfo &hostInfo)
{
Shiboken::GilState state;
Shiboken::AutoDecRef arglist(PyTuple_New(1));
auto *pyHostInfo = %CONVERTTOPYTHON[QHostInfo](hostInfo);
PyTuple_SET_ITEM(arglist.object(), 0, pyHostInfo);
- Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
- Py_DECREF(callable);
-};
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ release(); // single shot
+}
+// @snippet qhostinfo-lookuphost-functor
-Py_INCREF(callable);
-%CPPSELF.%FUNCTION_NAME(%1, cppCallback);
+// @snippet qhostinfo-lookuphost-callable
+%CPPSELF.%FUNCTION_NAME(%1, QHostInfoFunctor(%PYARG_2));
// @snippet qhostinfo-lookuphost-callable
// @snippet qipv6address-len
@@ -58,3 +66,65 @@ quint8 item = %CONVERTTOCPP[quint8](_value);
%CPPSELF.c[_i] = item;
return 0;
// @snippet qipv6address-setitem
+
+// @snippet qrestaccessmanager-functor
+class QRestFunctor
+{
+public:
+ explicit QRestFunctor(PyObject *callable) noexcept : m_callable(callable)
+ {
+ Py_INCREF(callable);
+ }
+
+ void operator()(QRestReply &restReply);
+
+private:
+ PyObject *m_callable;
+};
+
+void QRestFunctor::operator()(QRestReply &restReply)
+{
+ Q_ASSERT(m_callable);
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ auto *restReplyPtr = &restReply;
+ auto *pyRestReply = %CONVERTTOPYTHON[QRestReply*](restReplyPtr);
+ PyTuple_SET_ITEM(arglist.object(), 0, pyRestReply);
+ Shiboken::AutoDecRef ret(PyObject_CallObject(m_callable, arglist));
+ Py_DECREF(m_callable);
+ m_callable = nullptr;
+}
+// @snippet qrestaccessmanager-functor
+
+// @snippet qrestaccessmanager-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, QRestFunctor(%PYARG_3));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-callback
+
+// @snippet qrestaccessmanager-data-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, QRestFunctor(%PYARG_4));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-data-callback
+
+// @snippet qrestaccessmanager-method-data-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, QRestFunctor(%PYARG_5));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-method-data-callback
+
+// @snippet qrestreply-readjson
+QJsonParseError jsonParseError;
+std::optional<QJsonDocument> documentOptional = %CPPSELF.%FUNCTION_NAME(&jsonParseError);
+
+PyObject *pyDocument{};
+if (documentOptional.has_value()) {
+ const auto &document = documentOptional.value();
+ pyDocument = %CONVERTTOPYTHON[QJsonDocument](document);
+} else {
+ pyDocument = Py_None;
+ Py_INCREF(Py_None);
+}
+
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SetItem(%PYARG_0, 0, pyDocument);
+PyTuple_SetItem(%PYARG_0, 1, %CONVERTTOPYTHON[QJsonParseError](jsonParseError));
+// @snippet qrestreply-readjson
diff --git a/sources/pyside6/PySide6/glue/qtnetworkauth.cpp b/sources/pyside6/PySide6/glue/qtnetworkauth.cpp
index e22569e2e..7877a8dd5 100644
--- a/sources/pyside6/PySide6/glue/qtnetworkauth.cpp
+++ b/sources/pyside6/PySide6/glue/qtnetworkauth.cpp
@@ -1,12 +1,21 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// @snippet qabstractoauth-setmodifyparametersfunction
-auto callable = %PYARG_1;
-auto callback = [callable](QAbstractOAuth::Stage stage, QMultiMap<QString, QVariant>* dictPointer) -> void
+// @snippet qabstractoauth-lookuphost-functor
+struct QAbstractOAuthModifyFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(QAbstractOAuth::Stage stage, QMultiMap<QString, QVariant>* dictPointer);
+};
+
+void QAbstractOAuthModifyFunctor::operator()(QAbstractOAuth::Stage stage,
+ QMultiMap<QString, QVariant>* dictPointer)
{
+ auto *callable = object();
if (!PyCallable_Check(callable)) {
- qWarning("Argument 1 of %FUNCTION_NAME must be a callable.");
+ qWarning("Argument 1 of setModifyParametersFunction() must be a callable.");
return;
}
Shiboken::GilState state;
@@ -16,20 +25,20 @@ auto callback = [callable](QAbstractOAuth::Stage stage, QMultiMap<QString, QVari
PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMultiMap<QString, QVariant>](dict));
Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
- PyObject *key;
- PyObject *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(ret, &pos, &key, &value)) {
- QString cppKey = %CONVERTTOCPP[QString](key);
- QVariant cppValue = %CONVERTTOCPP[QVariant](value);
- dictPointer->replace(cppKey, cppValue);
+ if (!ret.isNull() && PyDict_Check(ret.object()) != 0) {
+ PyObject *key{};
+ PyObject *value{};
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(ret.object(), &pos, &key, &value)) {
+ QString cppKey = %CONVERTTOCPP[QString](key);
+ QVariant cppValue = %CONVERTTOCPP[QVariant](value);
+ dictPointer->replace(cppKey, cppValue);
+ }
}
+}
+// @snippet qabstractoauth-lookuphost-functor
- Py_DECREF(callable);
- return;
-
-};
-Py_INCREF(callable);
-%CPPSELF.%FUNCTION_NAME(callback);
+// @snippet qabstractoauth-setmodifyparametersfunction
+%CPPSELF.%FUNCTION_NAME(QAbstractOAuthModifyFunctor(%PYARG_1));
// @snippet qabstractoauth-setmodifyparametersfunction
diff --git a/sources/pyside6/PySide6/glue/qtpositioning.cpp b/sources/pyside6/PySide6/glue/qtpositioning.cpp
new file mode 100644
index 000000000..91c331c74
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtpositioning.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet darwin_location_permission_plugin
+#ifdef Q_OS_DARWIN
+#include<QtCore/qplugin.h>
+// register the static plugin and setup its metadata
+Q_IMPORT_PLUGIN(QDarwinLocationPermissionPlugin)
+#endif
+// @snippet darwin_location_permission_plugin
diff --git a/sources/pyside6/PySide6/glue/qtqml.cpp b/sources/pyside6/PySide6/glue/qtqml.cpp
index 20bcfff45..a56db8de6 100644
--- a/sources/pyside6/PySide6/glue/qtqml.cpp
+++ b/sources/pyside6/PySide6/glue/qtqml.cpp
@@ -62,3 +62,29 @@ return %CONVERTTOPYTHON[%RETURN_TYPE](retval);
// @snippet qmlsingleton
%PYARG_0 = PySide::Qml::qmlSingletonMacro(%ARGUMENT_NAMES);
// @snippet qmlsingleton
+
+// @snippet qqmlengine-singletoninstance-qmltypeid
+QJSValue instance = %CPPSELF.singletonInstance<QJSValue>(%1);
+if (instance.isNull()) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else if (instance.isQObject()) {
+ QObject *result = instance.toQObject();
+ %PYARG_0 = %CONVERTTOPYTHON[QObject *](result);
+} else {
+ %PYARG_0 = %CONVERTTOPYTHON[QJSValue](instance);
+}
+// @snippet qqmlengine-singletoninstance-qmltypeid
+
+// @snippet qqmlengine-singletoninstance-typename
+QJSValue instance = %CPPSELF.singletonInstance<QJSValue>(%1, %2);
+if (instance.isNull()) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else if (instance.isQObject()) {
+ QObject *result = instance.toQObject();
+ %PYARG_0 = %CONVERTTOPYTHON[QObject *](result);
+} else {
+ %PYARG_0 = %CONVERTTOPYTHON[QJSValue](instance);
+}
+// @snippet qqmlengine-singletoninstance-typename
diff --git a/sources/pyside6/PySide6/glue/qtquick.cpp b/sources/pyside6/PySide6/glue/qtquick.cpp
index 5b127ba24..060418faf 100644
--- a/sources/pyside6/PySide6/glue/qtquick.cpp
+++ b/sources/pyside6/PySide6/glue/qtquick.cpp
@@ -4,3 +4,24 @@
// @snippet qtquick
PySide::initQuickSupport(module);
// @snippet qtquick
+
+// @snippet qsgeometry-vertexdataaspoint2d
+auto *points = %CPPSELF->vertexDataAsPoint2D();
+const Py_ssize_t vertexCount = %CPPSELF->vertexCount();
+%PYARG_0 = PyList_New(vertexCount);
+for (Py_ssize_t i = 0; i < vertexCount; ++i) {
+ QSGGeometry::Point2D p = points[i];
+ PyList_SET_ITEM(%PYARG_0, i, %CONVERTTOPYTHON[QSGGeometry::Point2D](p));
+}
+// @snippet qsgeometry-vertexdataaspoint2d
+
+// @snippet qsgeometry-setvertexdataaspoint2d
+const qsizetype vertexCount = %CPPSELF->vertexCount();
+if (vertexCount != %1.size()) {
+ PyErr_SetString(PyExc_RuntimeError, "size mismatch");
+ return {};
+}
+
+QSGGeometry::Point2D *points = %CPPSELF->vertexDataAsPoint2D();
+std::copy(%1.cbegin(), %1.cend(), points);
+// @snippet qsgeometry-setvertexdataaspoint2d
diff --git a/sources/pyside6/PySide6/glue/qtquicktest.cpp b/sources/pyside6/PySide6/glue/qtquicktest.cpp
new file mode 100644
index 000000000..f41735ddf
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtquicktest.cpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet call-quick-test-main
+static int callQuickTestMain(const QString &name, QObject *setup,
+ QStringList argv, QString dir)
+{
+ if (dir.isEmpty())
+ dir = QDir::currentPath();
+ if (argv.isEmpty())
+ argv.append(name);
+
+ std::vector<QByteArray> argvB;
+ std::vector<char *> argvC;
+ const auto argc = argv.size();
+ argvB.reserve(argc);
+ argvC.reserve(argc);
+ for (const auto &arg : argv) {
+ argvB.emplace_back(arg.toUtf8());
+ argvC.push_back(argvB.back().data());
+ }
+
+ return quick_test_main_with_setup(int(argc), argvC.data(),
+ name.toUtf8().constData(),
+ dir.toUtf8().constData(), setup);
+}
+// @snippet call-quick-test-main
+
+// @snippet quick-test-main
+const int exitCode = callQuickTestMain(%1, nullptr, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[int](exitCode);
+// @snippet quick-test-main
+
+// @snippet quick-test-main_with_setup
+Shiboken::AutoDecRef pySetupObject(PyObject_CallObject(reinterpret_cast<PyObject *>(%2), nullptr));
+if (pySetupObject.isNull() || PyErr_Occurred() != nullptr)
+ return nullptr;
+
+/// Convenience to convert a PyObject to QObject
+QObject *setupObject = PySide::convertToQObject(pySetupObject.object(), true /* raiseError */);
+if (setupObject == nullptr)
+ return nullptr;
+
+const int exitCode = callQuickTestMain(%1, setupObject, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[int](exitCode);
+// @snippet quick-test-main_with_setup
diff --git a/sources/pyside6/PySide6/glue/qtstatemachine.cpp b/sources/pyside6/PySide6/glue/qtstatemachine.cpp
index 2d4973a04..098200b14 100644
--- a/sources/pyside6/PySide6/glue/qtstatemachine.cpp
+++ b/sources/pyside6/PySide6/glue/qtstatemachine.cpp
@@ -39,8 +39,9 @@ if (PySide::SignalManager::registerMetaMethod(%1, signalName.constData(),
// since it refers to a name very tied to the generator implementation.
// Check bug #362 for more information on this
// http://bugs.openbossa.org/show_bug.cgi?id=362
+// PYSIDE-2256: The label was removed
if (!PyObject_TypeCheck(%1, PySideSignalInstance_TypeF()))
- goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError;
+ return Shiboken::returnWrongArguments(args, fullName, errInfo);
PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%1);
auto sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance));
QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2);
diff --git a/sources/pyside6/PySide6/glue/qtuitools.cpp b/sources/pyside6/PySide6/glue/qtuitools.cpp
index 9e52436e7..1835ed096 100644
--- a/sources/pyside6/PySide6/glue/qtuitools.cpp
+++ b/sources/pyside6/PySide6/glue/qtuitools.cpp
@@ -45,7 +45,7 @@ static PyObject *QUiLoadedLoadUiFromDevice(QUiLoader *self, QIODevice *dev, QWid
}
if (!PyErr_Occurred())
- PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device");
+ PyErr_Format(PyExc_RuntimeError, "Unable to open/read ui device");
return nullptr;
}
@@ -62,7 +62,7 @@ Q_IMPORT_PLUGIN(PyCustomWidgets);
// @snippet quiloader-registercustomwidget
registerCustomWidget(%PYARG_1);
-%CPPSELF.addPluginPath(""); // force reload widgets
+%CPPSELF.addPluginPath(QString{}); // force reload widgets
// @snippet quiloader-registercustomwidget
// @snippet quiloader-load-1
@@ -87,38 +87,46 @@ char *arg1 = PyBytes_AsString(strObj);
QByteArray uiFileName(arg1);
Py_DECREF(strObj);
-QFile uiFile(uiFileName);
-
-if (!uiFile.exists()) {
- qCritical().noquote() << "File" << uiFileName << "does not exists";
+if (uiFileName.isEmpty()) {
+ qCritical() << "Error converting the UI filename to QByteArray";
Py_RETURN_NONE;
}
-if (uiFileName.isEmpty()) {
- qCritical() << "Error converting the UI filename to QByteArray";
+QFile uiFile(QString::fromUtf8(uiFileName));
+
+if (!uiFile.exists()) {
+ qCritical().noquote() << "File" << uiFileName << "does not exist";
Py_RETURN_NONE;
}
// Use the 'pyside6-uic' wrapper instead of 'uic'
// This approach is better than rely on 'uic' since installing
// the wheels cover this case.
-QString uicBin("pyside6-uic");
+QString uicBin(QStringLiteral("pyside6-uic"));
QStringList uicArgs = {QString::fromUtf8(uiFileName)};
QProcess uicProcess;
uicProcess.start(uicBin, uicArgs);
-if (!uicProcess.waitForFinished()) {
- qCritical() << "Cannot run 'pyside6-uic': " << uicProcess.errorString() << " - "
- << "Exit status " << uicProcess.exitStatus()
- << " (" << uicProcess.exitCode() << ")\n"
- << "Check if 'pyside6-uic' is in PATH";
+if (!uicProcess.waitForStarted()) {
+ qCritical().noquote() << "Cannot run '" << uicBin << "': "
+ << uicProcess.errorString() << " - Check if 'pyside6-uic' is in PATH";
+ Py_RETURN_NONE;
+}
+
+if (!uicProcess.waitForFinished()
+ || uicProcess.exitStatus() != QProcess::NormalExit
+ || uicProcess.exitCode() != 0) {
+ qCritical().noquote() << '\'' << uicBin << "' failed: "
+ << uicProcess.errorString() << " - Exit status " << uicProcess.exitStatus()
+ << " (" << uicProcess.exitCode() << ")\n";
Py_RETURN_NONE;
}
+
QByteArray uiFileContent = uicProcess.readAllStandardOutput();
QByteArray errorOutput = uicProcess.readAllStandardError();
if (!errorOutput.isEmpty()) {
- qCritical().noquote() << errorOutput;
+ qCritical().noquote() << '\'' << uicBin << "' failed: " << errorOutput;
Py_RETURN_NONE;
}
@@ -142,8 +150,8 @@ QXmlStreamReader reader(&uiFile);
while (!reader.atEnd() && baseClassName.isEmpty() && className.isEmpty()) {
auto token = reader.readNext();
if (token == QXmlStreamReader::StartElement && reader.name() == u"widget") {
- baseClassName = reader.attributes().value(QLatin1String("class")).toUtf8();
- className = reader.attributes().value(QLatin1String("name")).toUtf8();
+ baseClassName = reader.attributes().value(QLatin1StringView("class")).toUtf8();
+ className = reader.attributes().value(QLatin1StringView("name")).toUtf8();
}
}
diff --git a/sources/pyside6/PySide6/glue/qtwebenginecore.cpp b/sources/pyside6/PySide6/glue/qtwebenginecore.cpp
index a569e6c11..76a7c6d73 100644
--- a/sources/pyside6/PySide6/glue/qtwebenginecore.cpp
+++ b/sources/pyside6/PySide6/glue/qtwebenginecore.cpp
@@ -1,36 +1,64 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// @snippet qwebenginecookiestore-setcookiefilter
-auto callable = %PYARG_1;
-auto callback = [callable](const QWebEngineCookieStore::FilterRequest& filterRequest) -> bool
+// @snippet qwebenginecookiestore-functor
+struct QWebEngineCookieFilterFunctor : public Shiboken::PyObjectHolder
+{
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ bool operator()(const QWebEngineCookieStore::FilterRequest& filterRequest) const;
+};
+
+bool QWebEngineCookieFilterFunctor::operator()(const QWebEngineCookieStore::FilterRequest &
+ filterRequest) const
{
Shiboken::GilState state;
Shiboken::AutoDecRef arglist(PyTuple_New(1));
PyTuple_SET_ITEM(arglist, 0,
- %CONVERTTOPYTHON[QWebEngineCookieStore::FilterRequest](filterRequest));
- Py_INCREF(callable);
- PyObject* ret = PyObject_CallObject(callable, arglist);
- Py_DECREF(callable);
- return ret;
+ %CONVERTTOPYTHON[QWebEngineCookieStore::FilterRequest](filterRequest));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ return ret.object() == Py_True;
+}
+// @snippet qwebenginecookiestore-functor
-};
-%CPPSELF.%FUNCTION_NAME(callback);
+// @snippet qwebenginecookiestore-setcookiefilter
+%CPPSELF.%FUNCTION_NAME(QWebEngineCookieFilterFunctor(%PYARG_1));
// @snippet qwebenginecookiestore-setcookiefilter
-// @snippet qwebengineprofile-setnotificationpresenter
-auto callable = %PYARG_1;
-auto callback = [callable](std::unique_ptr<QWebEngineNotification> webEngineNotification) -> void
+// @snippet qwebengineprofile-functor
+struct QWebEngineNotificationFunctor : public Shiboken::PyObjectHolder
+{
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(std::unique_ptr<QWebEngineNotification> webEngineNotification);
+};
+
+void QWebEngineNotificationFunctor::operator()
+ (std::unique_ptr<QWebEngineNotification> webEngineNotification)
{
Shiboken::GilState state;
Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ auto *notification = webEngineNotification.release();
PyTuple_SET_ITEM(arglist.object(), 0,
- Shiboken::Conversions::pointerToPython(
- SbkPySide6_QtWebEngineCoreTypes[SBK_QWEBENGINENOTIFICATION_IDX],
- webEngineNotification.release()));
- Py_INCREF(callable);
- PyObject_CallObject(callable, arglist);
- Py_DECREF(callable);
+ %CONVERTTOPYTHON[QWebEngineNotification*](notification));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
};
-%CPPSELF.%FUNCTION_NAME(callback);
+// @snippet qwebengineprofile-functor
+
+// @snippet qwebengineprofile-setnotificationpresenter
+%CPPSELF.%FUNCTION_NAME(QWebEngineNotificationFunctor(%PYARG_1));
// @snippet qwebengineprofile-setnotificationpresenter
+
+// @snippet qwebenginepage-javascriptprompt-virtual-redirect
+std::pair<bool, QString> resultPair = javaScriptPromptPyOverride(gil, pyOverride.object(), securityOrigin, msg, defaultValue);
+result->assign(resultPair.second);
+return resultPair.first;
+// @snippet qwebenginepage-javascriptprompt-virtual-redirect
+
+// @snippet qwebenginepage-javascriptprompt-return
+QString str;
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, &str);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](str));
+// @snippet qwebenginepage-javascriptprompt-return
diff --git a/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp b/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp
index 8fdd6b693..af15130a4 100644
--- a/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp
+++ b/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp
@@ -55,8 +55,8 @@ auto callback = [callable](const QString &text)
PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](text));
Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
Py_DECREF(callable);
-
};
+
Py_INCREF(callable);
%CPPSELF.%FUNCTION_NAME(callback);
// @snippet qwebenginepage-convertto
@@ -95,8 +95,8 @@ auto callback = [callable](const QVariant &result)
// PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](found));
Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
Py_DECREF(callable);
-
};
+
Py_INCREF(callable);
%CPPSELF.%FUNCTION_NAME(%1, %2, callback);
// @snippet qwebenginepage-runjavascript
@@ -114,8 +114,8 @@ auto callback = [callable](const QByteArray &pdf)
PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QByteArray](pdf));
Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
Py_DECREF(callable);
-
};
+
Py_INCREF(callable);
%CPPSELF.%FUNCTION_NAME(callback, %2);
// @snippet qwebenginepage-printtopdf
diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp
index a70c0a6e1..f886106cf 100644
--- a/sources/pyside6/PySide6/glue/qtwidgets.cpp
+++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp
@@ -20,7 +20,8 @@ Shiboken::Object::releaseOwnership(%PYARG_0);
// @snippet qgraphicsitem
PyObject *userTypeConstant = PyLong_FromLong(QGraphicsItem::UserType);
-PyDict_SetItemString(Sbk_QGraphicsItem_TypeF()->tp_dict, "UserType", userTypeConstant);
+tpDict.reset(PepType_GetDict(Sbk_QGraphicsItem_TypeF()));
+PyDict_SetItemString(tpDict.object(), "UserType", userTypeConstant);
// @snippet qgraphicsitem
// @snippet qgraphicsitem-scene-return-parenting
@@ -74,7 +75,7 @@ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role));
%END_ALLOW_THREADS
%PYARG_0 = PyTuple_New(2);
PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
-PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](%5));
// @snippet qfiledialog-return
// @snippet qwidget-addaction-glue
@@ -213,11 +214,24 @@ if (_widget) {
// @snippet qtoolbox-removeitem
// @snippet qlayout-help-functions
+#ifndef _QLAYOUT_HELP_FUNCTIONS_
+#define _QLAYOUT_HELP_FUNCTIONS_ // Guard for jumbo builds
+
+static const char msgInvalidParameterAdd[] =
+ "Invalid parameter None passed to addLayoutOwnership().";
+static const char msgInvalidParameterRemoval[] =
+ "Invalid parameter None passed to removeLayoutOwnership().";
+
void addLayoutOwnership(QLayout *layout, QLayoutItem *item);
void removeLayoutOwnership(QLayout *layout, QWidget *widget);
inline void addLayoutOwnership(QLayout *layout, QWidget *widget)
{
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
+ return;
+ }
+
//transfer ownership to parent widget
QWidget *lw = layout->parentWidget();
QWidget *pw = widget->parentWidget();
@@ -244,6 +258,11 @@ inline void addLayoutOwnership(QLayout *layout, QWidget *widget)
inline void addLayoutOwnership(QLayout *layout, QLayout *other)
{
+ if (layout == nullptr || other == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
+ return;
+ }
+
//transfer all children widgets from other to layout parent widget
QWidget *parent = layout->parentWidget();
if (!parent) {
@@ -270,8 +289,11 @@ inline void addLayoutOwnership(QLayout *layout, QLayout *other)
inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item)
{
- if (!item)
+
+ if (layout == nullptr || item == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
return;
+ }
if (QWidget *w = item->widget()) {
addLayoutOwnership(layout, w);
@@ -287,6 +309,11 @@ inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item)
static void removeWidgetFromLayout(QLayout *layout, QWidget *widget)
{
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
+ return;
+ }
+
if (QWidget *parent = widget->parentWidget()) {
//give the ownership to parent
Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent));
@@ -304,6 +331,11 @@ static void removeWidgetFromLayout(QLayout *layout, QWidget *widget)
inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item)
{
+ if (layout == nullptr || item == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
+ return;
+ }
+
if (QWidget *w = item->widget()) {
removeWidgetFromLayout(layout, w);
} else {
@@ -319,8 +351,10 @@ inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item)
inline void removeLayoutOwnership(QLayout *layout, QWidget *widget)
{
- if (!widget)
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
return;
+ }
for (int i = 0, i_max = layout->count(); i < i_max; ++i) {
QLayoutItem *item = layout->itemAt(i);
@@ -330,15 +364,17 @@ inline void removeLayoutOwnership(QLayout *layout, QWidget *widget)
removeLayoutOwnership(layout, item);
}
}
+#endif // _QLAYOUT_HELP_FUNCTIONS_
// @snippet qlayout-help-functions
// @snippet qlayout-setalignment
%CPPSELF.setAlignment(%1);
// @snippet qlayout-setalignment
-// @snippet addownership-0
-addLayoutOwnership(%CPPSELF, %0);
-// @snippet addownership-0
+// @snippet addownership-item-at
+if (%0 != nullptr)
+ addLayoutOwnership(%CPPSELF, %0);
+// @snippet addownership-item-at
// @snippet addownership-1
addLayoutOwnership(%CPPSELF, %1);
@@ -385,7 +421,7 @@ Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
for (auto *item : items) {
SbkObject *obj = bm.retrieveWrapper(item);
if (obj) {
- if (reinterpret_cast<PyObject *>(obj)->ob_refcnt > 1) // If the refcnt is 1 the object will vannish anyway.
+ if (Py_REFCNT(reinterpret_cast<PyObject *>(obj)) > 1) // If the refcnt is 1 the object will vannish anyway.
Shiboken::Object::invalidate(obj);
Shiboken::Object::removeParent(obj);
}
@@ -434,11 +470,14 @@ for (int i = 0, count = %CPPSELF.count(); i < count; ++i) {
// @snippet qlistwidget-clear
// @snippet qwidget-retrieveobjectname
+#ifndef _RETRIEVEOBJECTNAME_
+#define _RETRIEVEOBJECTNAME_ // Guard for jumbo builds
static QByteArray retrieveObjectName(PyObject *obj)
{
Shiboken::AutoDecRef objName(PyObject_Str(obj));
return Shiboken::String::toCString(objName);
}
+#endif
// @snippet qwidget-retrieveobjectname
// @snippet qwidget-glue
@@ -508,15 +547,20 @@ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYSELF), "__style
// @snippet qwidget-style
QStyle *myStyle = %CPPSELF->style();
if (myStyle && qApp) {
-%PYARG_0 = %CONVERTTOPYTHON[QStyle *](myStyle);
+ bool keepReference = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QStyle *](myStyle);
QStyle *appStyle = qApp->style();
if (appStyle == myStyle) {
Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication *](qApp));
- Shiboken::Object::setParent(pyApp, %PYARG_0);
- Shiboken::Object::releaseOwnership(%PYARG_0);
- } else {
- Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYSELF), "__style__", %PYARG_0);
+ // Do not set parentship when qApp is embedded
+ if (Shiboken::Object::wasCreatedByPython(reinterpret_cast<SbkObject *>(pyApp.object()))) {
+ Shiboken::Object::setParent(pyApp, %PYARG_0);
+ Shiboken::Object::releaseOwnership(%PYARG_0);
+ keepReference = false;
+ }
}
+ if (keepReference)
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYSELF), "__style__", %PYARG_0);
}
// @snippet qwidget-style
@@ -695,49 +739,49 @@ const char *styleOptionType(const QStyleOption *o)
case QStyleOption::SO_Default:
break;
case QStyleOption::SO_FocusRect:
- return "StyleOptionFocusRect";
+ return "QStyleOptionFocusRect";
case QStyleOption::SO_Button:
- return "StyleOptionButton";
+ return "QStyleOptionButton";
case QStyleOption::SO_Tab:
- return "StyleOptionTab";
+ return "QStyleOptionTab";
case QStyleOption::SO_MenuItem:
- return "StyleOptionMenuItem";
+ return "QStyleOptionMenuItem";
case QStyleOption::SO_Frame:
- return "StyleOptionFrame";
+ return "QStyleOptionFrame";
case QStyleOption::SO_ProgressBar:
- return "StyleOptionProgressBar";
+ return "QStyleOptionProgressBar";
case QStyleOption::SO_ToolBox:
- return "StyleOptionToolBox";
+ return "QStyleOptionToolBox";
case QStyleOption::SO_Header:
- return "StyleOptionHeader";
+ return "QStyleOptionHeader";
case QStyleOption::SO_DockWidget:
- return "StyleOptionDockWidget";
+ return "QStyleOptionDockWidget";
case QStyleOption::SO_ViewItem:
- return "StyleOptionViewItem";
+ return "QStyleOptionViewItem";
case QStyleOption::SO_TabWidgetFrame:
- return "StyleOptionTabWidgetFrame";
+ return "QStyleOptionTabWidgetFrame";
case QStyleOption::SO_TabBarBase:
- return "StyleOptionTabBarBase";
+ return "QStyleOptionTabBarBase";
case QStyleOption::SO_RubberBand:
- return "StyleOptionRubberBand";
+ return "QStyleOptionRubberBand";
case QStyleOption::SO_ToolBar:
- return "StyleOptionToolBar";
+ return "QStyleOptionToolBar";
case QStyleOption::SO_GraphicsItem:
- return "StyleOptionGraphicsItem";
+ return "QStyleOptionGraphicsItem";
case QStyleOption::SO_Slider:
- return "StyleOptionSlider";
+ return "QStyleOptionSlider";
case QStyleOption::SO_SpinBox:
- return "StyleOptionSpinBox";
+ return "QStyleOptionSpinBox";
case QStyleOption::SO_ToolButton:
- return "StyleOptionToolButton";
+ return "QStyleOptionToolButton";
case QStyleOption::SO_ComboBox:
- return "StyleOptionComboBox";
+ return "QStyleOptionComboBox";
case QStyleOption::SO_TitleBar:
- return "StyleOptionTitleBar";
+ return "QStyleOptionTitleBar";
case QStyleOption::SO_GroupBox:
- return "StyleOptionGroupBox";
+ return "QStyleOptionGroupBox";
case QStyleOption::SO_SizeGrip:
- return "StyleOptionSizeGrip";
+ return "QStyleOptionSizeGrip";
default:
break;
}
@@ -745,6 +789,26 @@ const char *styleOptionType(const QStyleOption *o)
}
// @snippet qstyleoption-typename
+// @snippet qwizardpage-registerfield
+auto *signalInst = reinterpret_cast<PySideSignalInstance *>(%PYARG_4);
+const auto data = PySide::Signal::getEmitterData(signalInst);
+if (data.methodIndex == -1)
+ return PyErr_Format(PyExc_RuntimeError, "QWizardPage::registerField(): Unable to retrieve signal emitter.");
+const auto method = data.emitter->metaObject()->method(data.methodIndex);
+const QByteArray signature = QByteArrayLiteral("2") + method.methodSignature();
+%BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(%1, %2, %3, signature.constData());
+%END_ALLOW_THREADS
+// @snippet qwizardpage-registerfield
+
+// The constructor heuristics generate setting a parent-child relationship
+// when creating a QDialog with parent. This causes the dialog to leak
+// when it synchronous exec() is used instead of asynchronous show().
+// In that case, remove the parent-child relationship.
+// @snippet qdialog-exec-remove-parent-relation
+Shiboken::Object::removeParent(reinterpret_cast<SbkObject *>(%PYSELF));
+// @snippet qdialog-exec-remove-parent-relation
+
/*********************************************************************
* CONVERSIONS
********************************************************************/