diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9ca66c53c..48f94ee9f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -52,7 +52,7 @@ jobs:
uses: actions/checkout@v6
- name: Ccache
- uses: hendrikmuhs/ccache-action@v1.2.20
+ uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-ubuntu-${{ matrix.container_version }}
evict-old-files: 'job'
@@ -122,7 +122,7 @@ jobs:
make check TESTARGS="-platform minimal"
- name: Upload Wrappers
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v7
with:
name: wrappers_ubuntu_${{ matrix.container_version }}
path: generated_cpp
@@ -195,7 +195,7 @@ jobs:
make check TESTARGS="-platform offscreen"
- name: Upload Wrappers
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v7
with:
name: wrappers_${{ matrix.container_os }}-${{ matrix.container_os_version }}_${{ matrix.configuration }}
path: generated_cpp
@@ -235,7 +235,7 @@ jobs:
uses: actions/checkout@v6
- name: Ccache
- uses: hendrikmuhs/ccache-action@v1.2.20
+ uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-${{ matrix.qt-version }}
evict-old-files: 'job'
@@ -298,7 +298,7 @@ jobs:
- name: Upload Wrappers
if: ${{ contains(matrix.configuration, 'release') }}
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v7
with:
name: wrappers_macos${{ steps.versions.outputs.MACOS_VERSION_SHORT }}_qt${{ steps.versions.outputs.QT_VERSION_SHORT }}
path: generated_cpp
@@ -347,7 +347,7 @@ jobs:
uses: actions/checkout@v6
- name: Reset PATH
- uses: egor-tensin/cleanup-path@v4
+ uses: egor-tensin/cleanup-path@v5
- name: Install MSVC++
uses: ilammy/msvc-dev-cmd@v1
@@ -421,7 +421,7 @@ jobs:
- name: Upload Wrappers
if: (matrix.pythonqtall-config || '') == ''
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v7
with:
name: wrappers_${{ matrix.qt-arch }}_${{ steps.versions.outputs.QT_VERSION_SHORT }}
path: generated_cpp
diff --git a/.github/workflows/build_latest.yml b/.github/workflows/build_latest.yml
index fe9729bc4..9d421f030 100644
--- a/.github/workflows/build_latest.yml
+++ b/.github/workflows/build_latest.yml
@@ -47,7 +47,7 @@ jobs:
uses: actions/checkout@v6
- name: Ccache
- uses: hendrikmuhs/ccache-action@v1.2.20
+ uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-${{ matrix.qt-version }}
evict-old-files: 'job'
@@ -92,7 +92,7 @@ jobs:
--output-directory=.
- name: Upload Wrappers
- uses: actions/upload-artifact@v5
+ uses: actions/upload-artifact@v7
with:
name: wrappers_${{ matrix.os }}_${{ steps.setenv.outputs.QT_VERSION_SHORT }}
path: generated_cpp
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 94fe31d6a..5db7b28b0 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
- rev: "v21.1.7"
+ rev: "v22.1.5"
hooks:
- id: clang-format
diff --git a/generator/main.cpp b/generator/main.cpp
index 251e41043..945d6b289 100644
--- a/generator/main.cpp
+++ b/generator/main.cpp
@@ -307,7 +307,8 @@ bool preprocess(const QString& sourceFile, const QString& targetFile, const QStr
unsigned int getQtVersion(const QStringList& paths)
{
- QRegularExpression re("#define\\s+QTCORE_VERSION\\s+0x([0-9a-f]+)", QRegularExpression::CaseInsensitiveOption);
+ QRegularExpression re(R"*(#define\s+QTCORE_VERSION_STR\s+"(\d+)\.(\d+)\.(\d+)")*",
+ QRegularExpression::CaseInsensitiveOption);
// Iterate through provided paths to find the qtcoreversion.h header file
for (const QString& path : paths) {
@@ -340,14 +341,7 @@ unsigned int getQtVersion(const QStringList& paths)
f.close();
auto match = re.match(content);
if (match.isValid()) {
- unsigned int result;
- bool ok;
- result = match.captured(1).toUInt(&ok, 16);
- if (!ok) {
- printf("Could not parse Qt version in file [%s] (looked for #define QTCORE_VERSION)\n",
- qPrintable(filePath));
- }
- return result;
+ return (match.captured(1).toUInt() << 16) + (match.captured(2).toUInt() << 8) + match.captured(3).toUInt();
}
}
}
diff --git a/generator/typesystem_core.xml b/generator/typesystem_core.xml
index 6678e9331..46d1b8508 100644
--- a/generator/typesystem_core.xml
+++ b/generator/typesystem_core.xml
@@ -75,6 +75,7 @@
+
@@ -973,6 +974,24 @@ public:
+
+
+
+ // Workaround for std::optional parameters in Qt 6.10
+ bool mkpath(QDir* theWrappedObject, const QString& dirPath) const {
+ return theWrappedObject->mkpath(dirPath);
+ }
+ bool mkdir(QDir* theWrappedObject, const QString& dirName) const {
+ return theWrappedObject->mkdir(dirName);
+ }
+ bool mkpath(QDir* theWrappedObject, const QString& dirPath, QFile::Permissions permissions) const {
+ return theWrappedObject->mkpath(dirPath, permissions);
+ }
+ bool mkdir(QDir* theWrappedObject, const QString& dirName, QFile::Permissions permissions) const {
+ return theWrappedObject->mkdir(dirName, permissions);
+ }
+
@@ -2162,7 +2181,25 @@ public:
-
+
+
+
+ void py_set_offset(QJsonParseError* theWrappedObject, int offset){
+ theWrappedObject->offset = offset;
+ }
+ int py_get_offset(QJsonParseError* theWrappedObject){
+ return theWrappedObject->offset;
+ }
+
+
+ void py_set_offset(QJsonParseError* theWrappedObject, qint64 offset){
+ theWrappedObject->offset = offset;
+ }
+ qint64 py_get_offset(QJsonParseError* theWrappedObject){
+ return theWrappedObject->offset;
+ }
+
+
diff --git a/generator/typesystem_gui.xml b/generator/typesystem_gui.xml
index 90f7e2063..582994b46 100644
--- a/generator/typesystem_gui.xml
+++ b/generator/typesystem_gui.xml
@@ -974,6 +974,7 @@
+
@@ -2336,6 +2337,7 @@ PyObject* constScanLine(QImage* image, int line) {
+
diff --git a/generator/typesystem_multimedia.xml b/generator/typesystem_multimedia.xml
index b2c326978..26cb9c246 100644
--- a/generator/typesystem_multimedia.xml
+++ b/generator/typesystem_multimedia.xml
@@ -87,7 +87,15 @@
-
+
+
+
+ float static_QAudio_convertVolume(float volume, QAudio::VolumeScale from, QAudio::VolumeScale to)
+ {
+ return (QtAudio::convertVolume(volume, from, to));
+ }
+
+
@@ -226,6 +234,7 @@
+
diff --git a/generator/typesystem_xml.xml b/generator/typesystem_xml.xml
index cc82bcf36..7191846b3 100644
--- a/generator/typesystem_xml.xml
+++ b/generator/typesystem_xml.xml
@@ -10,6 +10,7 @@
+
diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp
index 2b016ec83..c7e76ea61 100644
--- a/src/PythonQt.cpp
+++ b/src/PythonQt.cpp
@@ -121,7 +121,11 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList");
qRegisterMetaType>("QList");
- qRegisterMetaType("QObjectList");
+ // QObjectList might already be registered by other modules (e.g. QtScript) or under different type names.
+ // To avoid conflicts or warnings, only register it if it is currently unknown.
+ if (QMetaType::type("QObjectList") == QMetaType::UnknownType) {
+ qRegisterMetaType("QObjectList");
+ }
qRegisterMetaType>("QList");
if (QT_POINTER_SIZE == 8) {
qRegisterMetaType("size_t");
diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp
index 96da8be47..3021a04c5 100644
--- a/src/PythonQtConversion.cpp
+++ b/src/PythonQtConversion.cpp
@@ -592,24 +592,21 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
{
QByteArray bytes = PyObjGetBytesAllowString(obj, strict, ok);
if (ok) {
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(bytes), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
+ ptr = frame->establishPersistentPtr(alreadyAllocatedCPPObject, bytes);
}
} break;
case QMetaType::QString:
{
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(str), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
+ ptr = frame->establishPersistentPtr(alreadyAllocatedCPPObject, str);
}
} break;
case QMetaType::QStringList:
{
QStringList l = PyObjToStringList(obj, strict, ok);
if (ok) {
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame, QVariant(l), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
+ ptr = frame->establishPersistentPtr(alreadyAllocatedCPPObject, l);
}
} break;
@@ -649,7 +646,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
void* ptr2 = nullptr;
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
+ PythonQtArgumentFrame_ADD_VARIANT_VALUE(frame, QVariant(str), ptr2);
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
QVariant::fromValue(QStringRef((const QString*)((QVariant*)ptr2)->constData())), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
@@ -663,12 +660,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
// Handle QStringView, which needs a reference to a persistent QString
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
- void* ptr2 = nullptr;
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
- QVariant::fromValue(QStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
- return ptr;
+ return frame->establishPersistentViewPtr(alreadyAllocatedCPPObject, str);
} else {
return nullptr;
}
@@ -676,12 +668,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
// Handle QAnyStringView, which needs a reference to a persistent QString
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
- void* ptr2 = nullptr;
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(str), ptr2);
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
- QVariant::fromValue(QAnyStringView(*((const QString*)((QVariant*)ptr2)->constData()))), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
- return ptr;
+ return frame->establishPersistentViewPtr(alreadyAllocatedCPPObject, str);
} else {
return nullptr;
}
@@ -689,12 +676,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
// Handle QByteArrayView, which needs a reference to a persistent QByteArray
QByteArray ba = PyObjGetBytesAllowString(obj, strict, ok);
if (ok) {
- void* ptr2 = nullptr;
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(ba), ptr2);
- PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
- QVariant::fromValue(QByteArrayView(*((const QByteArray*)((QVariant*)ptr2)->constData()))), ptr);
- ptr = (void*)((QVariant*)ptr)->constData();
- return ptr;
+ return frame->establishPersistentViewPtr(alreadyAllocatedCPPObject, ba);
} else {
return nullptr;
}
diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h
index 2460876ab..f67d0a738 100644
--- a/src/PythonQtConversion.h
+++ b/src/PythonQtConversion.h
@@ -122,6 +122,7 @@ class PYTHONQT_EXPORT PythonQtConv
static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data);
//! convert python object to Qt (according to the given parameter) and if the conversion should be strict (classInfo is currently not used anymore)
+ //! If an alreadyAllocatedCPPObject is used it must have the same type as given by info.typeId
static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict,
PythonQtClassInfo* classInfo, void* alreadyAllocatedCPPObject, PythonQtArgumentFrame* frame = nullptr);
diff --git a/src/PythonQtMisc.h b/src/PythonQtMisc.h
index 5c8a70b00..abc824163 100644
--- a/src/PythonQtMisc.h
+++ b/src/PythonQtMisc.h
@@ -121,6 +121,35 @@ class PythonQtArgumentFrame
//! Get next pointer to a POD.
quint64* nextPODPtr();
+ template
+ void* establishPersistentPtr(void* alreadyAllocatedPtr, const Class& value)
+ {
+ if (alreadyAllocatedPtr) {
+ *reinterpret_cast(alreadyAllocatedPtr) = value;
+ return alreadyAllocatedPtr;
+ } else {
+ QVariant* item = nextVariantPtr();
+ *item = QVariant(value);
+ return const_cast(item->constData());
+ }
+ }
+
+ template
+ void* establishPersistentViewPtr(void* alreadyAllocatedPtr, const Class& value)
+ {
+ QVariant* itemStore = nextVariantPtr();
+ *itemStore = QVariant(value);
+ if (alreadyAllocatedPtr) {
+ *reinterpret_cast(alreadyAllocatedPtr) =
+ ViewClass(*reinterpret_cast(itemStore->constData()));
+ return alreadyAllocatedPtr;
+ } else {
+ QVariant* item = nextVariantPtr();
+ *item = QVariant::fromValue(ViewClass(*reinterpret_cast(itemStore->constData())));
+ return const_cast(item->constData());
+ }
+ }
+
private:
PythonQtArgumentFrame();
~PythonQtArgumentFrame();
diff --git a/src/PythonQtStdDecorators.cpp b/src/PythonQtStdDecorators.cpp
index 25ba6b300..2668949c3 100644
--- a/src/PythonQtStdDecorators.cpp
+++ b/src/PythonQtStdDecorators.cpp
@@ -270,17 +270,14 @@ QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* t
return list;
}
-QObject* PythonQtStdDecorators::findChild(QObject* parent, const char* typeName, const QMetaObject* meta,
+QObject* PythonQtStdDecorators::findChild(const QObject* parent, const char* typeName, const QMetaObject* meta,
const QString& name)
{
const QObjectList& children = parent->children();
- int i;
- for (i = 0; i < children.size(); ++i) {
- QObject* obj = children.at(i);
-
+ for (QObject* obj : children) {
if (!obj)
- return nullptr;
+ continue;
// Skip if the name doesn't match.
if (!name.isNull() && obj->objectName() != name)
@@ -290,69 +287,55 @@ QObject* PythonQtStdDecorators::findChild(QObject* parent, const char* typeName,
return obj;
}
- for (i = 0; i < children.size(); ++i) {
- QObject* obj = findChild(children.at(i), typeName, meta, name);
+ for (QObject* child : children) {
+ if (child) {
+ QObject* obj = findChild(child, typeName, meta, name);
- if (obj != nullptr)
- return obj;
+ if (obj != nullptr)
+ return obj;
+ }
}
return nullptr;
}
-int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, const QMetaObject* meta,
+void PythonQtStdDecorators::findChildren(const QObject* parent, const char* typeName, const QMetaObject* meta,
const QString& name, QList& list)
{
const QObjectList& children = parent->children();
- int i;
-
- for (i = 0; i < children.size(); ++i) {
- QObject* obj = children.at(i);
+ for (QObject* obj : children) {
if (!obj)
- return -1;
-
- // Skip if the name doesn't match.
- if (!name.isNull() && obj->objectName() != name)
continue;
- if ((typeName && obj->inherits(typeName)) || (meta && meta->cast(obj))) {
- list += obj;
+ if (name.isNull() || obj->objectName() == name) {
+ if ((typeName && obj->inherits(typeName)) || (meta && meta->cast(obj))) {
+ list += obj;
+ }
}
- if (findChildren(obj, typeName, meta, name, list) < 0)
- return -1;
+ findChildren(obj, typeName, meta, name, list);
}
-
- return 0;
}
-int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, const QMetaObject* meta,
+void PythonQtStdDecorators::findChildren(const QObject* parent, const char* typeName, const QMetaObject* meta,
const QRegularExpression& regExp, QList& list)
{
const QObjectList& children = parent->children();
- int i;
-
- for (i = 0; i < children.size(); ++i) {
- QObject* obj = children.at(i);
+ for (QObject* obj : children) {
if (!obj)
- return -1;
-
- // Skip if the name doesn't match.
- QRegularExpressionMatch match = regExp.match(obj->objectName());
- if (match.hasMatch() == false)
continue;
- if ((typeName && obj->inherits(typeName)) || (meta && meta->cast(obj))) {
- list += obj;
+ QRegularExpressionMatch match = regExp.match(obj->objectName());
+ if (match.hasMatch()) {
+ if ((typeName && obj->inherits(typeName)) || (meta && meta->cast(obj))) {
+ list += obj;
+ }
}
- if (findChildren(obj, typeName, meta, regExp, list) < 0)
- return -1;
+ findChildren(obj, typeName, meta, regExp, list);
}
-
- return 0;
}
const QMetaObject* PythonQtStdDecorators::metaObject(QObject* obj)
diff --git a/src/PythonQtStdDecorators.h b/src/PythonQtStdDecorators.h
index aa5771c74..47467e3ce 100644
--- a/src/PythonQtStdDecorators.h
+++ b/src/PythonQtStdDecorators.h
@@ -151,11 +151,11 @@ public Q_SLOTS:
void static_QTimer_singleShot(int msec, PyObject* callable);
private:
- QObject* findChild(QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name);
- int findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name,
- QList& list);
- int findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QRegularExpression& regExp,
+ QObject* findChild(const QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name);
+ void findChildren(const QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name,
QList& list);
+ void findChildren(const QObject* parent, const char* typeName, const QMetaObject* meta,
+ const QRegularExpression& regExp, QList& list);
};
class PythonQtSingleShotTimer : public QTimer