[neon/forks/pyqt6/Neon/release] /: New upstream version 6.10.1
Dmitry Shachnev
null at kde.org
Mon Jul 27 14:39:11 BST 2026
Git commit 0380835252971314da716d700e028abb8668c268 by Dmitry Shachnev.
Committed on 09/12/2025 at 12:44.
Pushed by carlosdem into branch 'Neon/release'.
New upstream version 6.10.1
M +53 -0 ChangeLog
M +7 -0 NEWS
M +1 -1 PKG-INFO
A +114 -0 examples/itemmodels/rangemodel.py
M +0 -3 lupdate/python_source.py
M +1 -1 pyproject.toml
M +1 -0 qpy/QtCore/qpycore_post_init.cpp
M +25 -0 qpy/QtCore/qpycore_pyqtpyobject.cpp
M +1 -0 qpy/QtCore/qpycore_pyqtpyobject.h
A +345 -0 qpy/QtCore/qpycore_qrangemodel.cpp [License: GPL (v3)]
A +128 -0 qpy/QtCore/qpycore_qrangemodel.h [License: GPL (v3)]
M +3 -2 sip/QtCore/QtCoremod.sip
M +45 -25 sip/QtCore/qobject.sip
C +47 -3 sip/QtCore/qpycore_qrangemodel.sip [from: sip/QtCore/qrangemodel.sip - 050% similarity]
M +76 -0 sip/QtCore/qrangemodel.sip
M +1 -1 sip/QtWidgets/qlineedit.sip
M +3 -3 sip/QtWidgets/qplaintextedit.sip
M +1 -1 sip/QtWidgets/qscrollbar.sip
M +3 -3 sip/QtWidgets/qtextedit.sip
https://invent.kde.org/neon/forks/pyqt6/-/commit/0380835252971314da716d700e028abb8668c268
diff --git a/ChangeLog b/ChangeLog
index 13ecad9..c27ea16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+commit d72db36074a3453ef6a5a5746082230b2afe4913
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Fri Dec 5 14:37:07 2025 +0000
+
+ Release v6.10.1
+
+commit 48796838b960e1c9a7f2c66afa810034f2795a06
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Thu Nov 27 21:58:59 2025 +0000
+
+ Bug fixes
+
+ - Fixed ownership issues with the result of calls to
+ `createStandardContextMenu()` and `createMimeDataFromSelection()`.
+
+commit 6531d8a843928be180d317708ed759525e665082
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Mon Nov 10 19:12:44 2025 +0000
+
+ Support for `QRangeModel`
+
+ The support for `QRangeModel` was refactored to replace `QPyRange` with
+ `QPyAbstractRange`, `QPySequenceRange` and `QPyTableRange`.
+
+commit 3a6f12e54c4f85954cc727fee632b770915a5992
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Mon Nov 10 10:50:42 2025 +0000
+
+ Development regressions
+
+ - Fixed the support for QRangeModel for Python v3.9.
+
+commit 45477b08afa039072abf38b9e6832153bcd7e5d5
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Sun Nov 9 15:39:50 2025 +0000
+
+ Support for `QRangeModel`
+
+ Support was added for `QRangeModel` (added in Qt v6.10). This allows a
+ range of Python objects to be edited in-situ using an appropriate Qt view.
+ Currently a range may be a sequence of Python objects or a table (ie. a
+ sequence of sequences). Support for trees is planned to be added in a
+ later release. Ranges are wrapped using the `QPyRange` class which is then
+ passed to `QRangeModel`.
+
+commit bcfacbbd491136b2a4a22c52646a36886d89f774
+Author: Phil Thompson <phil at riverbankcomputing.com>
+Date: Sat Nov 1 12:15:08 2025 +0000
+
+ Bug fixes
+
+ - Fixed a regression in `pylupdate6` when using Python v3.14.
+
commit ecab96d9ca996c2496594c3a06d4cea1de93f395
Author: Phil Thompson <phil at riverbankcomputing.com>
Date: Thu Oct 16 10:55:25 2025 +0100
diff --git a/NEWS b/NEWS
index b6df794..ea9d588 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,10 @@
+v6.10.1 5th December 2025
+ - Added support for `QRangeModel` (and related `QPyAbstractRange`,
+ `QPySequenceRange` and `QPyTableRange`).
+ - Fixed a regression in `pylupdate6` when using Python v3.14.
+ - Fixed ownership issues with the result of calls to
+ `createStandardContextMenu()` and `createMimeDataFromSelection()`.
+
v6.10.0 16th October 2025
- Added support for Qt v6.10 (excluding QRangeModel).
- Added support for QGuiApplication.nativeInterface().
diff --git a/PKG-INFO b/PKG-INFO
index 2fb2568..f172b41 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: PyQt6
-Version: 6.10.0
+Version: 6.10.1
Requires-Python: >=3.9
Summary: Python bindings for the Qt cross platform application toolkit
Description-Content-Type: text/markdown
diff --git a/examples/itemmodels/rangemodel.py b/examples/itemmodels/rangemodel.py
new file mode 100644
index 0000000..9d93e06
--- /dev/null
+++ b/examples/itemmodels/rangemodel.py
@@ -0,0 +1,114 @@
+import sys
+
+from PyQt6.QtCore import QPySequenceRange, QPyTableRange, QRangeModel, Qt
+from PyQt6.QtWidgets import (QApplication, QGridLayout, QLabel, QListView,
+ QTableView, QTreeView, QVBoxLayout, QWidget)
+
+
+class ViewContainer(QVBoxLayout):
+ """ A container for a view. """
+
+ def __init__(self, title, py_range, parent=None):
+ """ Initialise the view. """
+
+ super().__init__(parent)
+
+ self._py_range = py_range
+
+ if isinstance(py_range, QPySequenceRange):
+ py_range.dataChanged.connect(self._on_sequence_changed)
+ view = QListView()
+
+ if isinstance(py_range, QPyTableRange):
+ py_range.dataChanged.connect(self._on_table_changed)
+ view = QTableView()
+ view.horizontalHeader().setVisible(False)
+ view.verticalHeader().setVisible(False)
+
+ model = QRangeModel(py_range)
+ view.setModel(model)
+ view.selectionModel().currentChanged.connect(
+ self._on_selection_changed)
+
+ self._data_view = QLabel()
+
+ self.addWidget(
+ QLabel(f'<b>{title}</b>',
+ alignment=Qt.AlignmentFlag.AlignHCenter))
+ self.addWidget(view)
+ self.addWidget(self._data_view)
+
+ def _on_selection_changed(self, current, _):
+ """ Handle the changed selection. """
+
+ self._set_data_view(current.row(), current.column())
+
+ def _on_sequence_changed(self, index):
+ """ Handle the changed Python sequence. """
+
+ self._set_data_view(index)
+
+ def _on_table_changed(self, row, column):
+ """ Handle the changed Python table. """
+
+ self._set_data_view(row, column)
+
+ def _set_data_view(self, row, column=-1):
+ """ Set the view of an element from the Python data. """
+
+ datum = self._py_range.data()[row]
+ if isinstance(self._py_range, QPyTableRange):
+ datum = datum[column]
+
+ self._data_view.setText(f"Selected data: {repr(datum)}")
+
+
+# Instances of this type are unknown to PyQt.
+class Data:
+ """ Wrap an arbitrary Python object. """
+
+ def __init__(self, data):
+ """ Initialise the object. """
+
+ self._data = data
+
+ def __str__(self):
+ """ Return a string representation of the data to be used in views. """
+
+ return str(self._data)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ gallery = QWidget()
+ layout = QGridLayout()
+
+ ro_seq_data = QPySequenceRange(
+ ("Foo", 1, True, 5.6, Data("A string"), Data(100)))
+ layout.addLayout(ViewContainer("Read-only Sequence", ro_seq_data), 0, 0)
+
+ fixed_seq_data = QPySequenceRange(["Cat", 9, False], editable=True)
+ layout.addLayout(ViewContainer("Fixed Size Sequence", fixed_seq_data), 0,
+ 1)
+
+ ro_table_data = QPyTableRange(
+ (
+ ("Foo", 1, True, 5.6, Data("A string"), Data(100)),
+ ("Bar", 2, False, 6.6, Data("Another string"), Data(200)),
+ ))
+ layout.addLayout(ViewContainer("Read-only Table", ro_table_data), 1, 0)
+
+ fixed_table_data = QPyTableRange(
+ (
+ ["Cat", 9, False],
+ ["Dog", 1, True],
+ ),
+ editable=True)
+ layout.addLayout(ViewContainer("Fixed Size Table", fixed_table_data), 1, 1)
+
+ gallery.setLayout(layout)
+ gallery.resize(1400, 600)
+ gallery.show()
+
+ sys.exit(app.exec())
diff --git a/lupdate/python_source.py b/lupdate/python_source.py
index fe001e4..aa5f004 100644
--- a/lupdate/python_source.py
+++ b/lupdate/python_source.py
@@ -224,9 +224,6 @@ class Visitor(ast.NodeVisitor):
node.
"""
- if isinstance(node, ast.Str):
- return node.s
-
if isinstance(node, ast.Constant):
if isinstance(node.value, str):
return node.value
diff --git a/pyproject.toml b/pyproject.toml
index 2b59362..20a11a1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "sipbuild.api"
[project]
name = "PyQt6"
-version = "6.10.0"
+version = "6.10.1"
description = "Python bindings for the Qt cross platform application toolkit"
readme = "README.md"
urls.homepage = "https://www.riverbankcomputing.com/software/pyqt/"
diff --git a/qpy/QtCore/qpycore_post_init.cpp b/qpy/QtCore/qpycore_post_init.cpp
index ed2f409..fb6fe54 100644
--- a/qpy/QtCore/qpycore_post_init.cpp
+++ b/qpy/QtCore/qpycore_post_init.cpp
@@ -78,6 +78,7 @@ void qpycore_post_init(PyObject *module_dict)
// Register the C++ type that wraps Python objects.
qRegisterMetaType<PyQt_PyObject>("PyQt_PyObject");
+ QMetaType::registerConverter<PyQt_PyObject, QString>();
// Register the lazy attribute getter.
if (sipRegisterAttributeGetter(sipType_QObject, qpycore_get_lazy_attr) < 0)
diff --git a/qpy/QtCore/qpycore_pyqtpyobject.cpp b/qpy/QtCore/qpycore_pyqtpyobject.cpp
index 4cf89c1..487a9d0 100644
--- a/qpy/QtCore/qpycore_pyqtpyobject.cpp
+++ b/qpy/QtCore/qpycore_pyqtpyobject.cpp
@@ -90,6 +90,31 @@ PyQt_PyObject &PyQt_PyObject::operator=(const PyQt_PyObject &other)
}
+// QString operator cast.
+PyQt_PyObject::operator QString() const
+{
+ QString qs;
+
+ SIP_BLOCK_THREADS
+
+ PyObject *py_s = PyObject_Str(pyobject);
+
+ if (py_s)
+ {
+ qs = qpycore_PyObject_AsQString(py_s);
+ Py_DECREF(py_s);
+ }
+ else
+ {
+ qs = QString("PyQt_PyObject string conversion failed");
+ }
+
+ SIP_UNBLOCK_THREADS
+
+ return qs;
+}
+
+
// Comparison operator. It must be global to be available to QMetaType.
bool operator==(const PyQt_PyObject &self, const PyQt_PyObject &other)
{
diff --git a/qpy/QtCore/qpycore_pyqtpyobject.h b/qpy/QtCore/qpycore_pyqtpyobject.h
index 9ba5cf7..18420ef 100644
--- a/qpy/QtCore/qpycore_pyqtpyobject.h
+++ b/qpy/QtCore/qpycore_pyqtpyobject.h
@@ -40,6 +40,7 @@ public:
~PyQt_PyObject();
PyQt_PyObject &operator=(const PyQt_PyObject &other);
+ operator QString() const;
// The Python object being wrapped.
PyObject *pyobject;
diff --git a/qpy/QtCore/qpycore_qrangemodel.cpp b/qpy/QtCore/qpycore_qrangemodel.cpp
new file mode 100644
index 0000000..b9465ea
--- /dev/null
+++ b/qpy/QtCore/qpycore_qrangemodel.cpp
@@ -0,0 +1,345 @@
+// This is the support for QRangeModel.
+//
+// Copyright (c) 2025 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt6.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+#include <Python.h>
+
+#include <qglobal.h>
+
+#if QT_VERSION >= 0x060a00
+
+#include "qpycore_qrangemodel.h"
+
+#include "qpycore_api.h"
+
+#include "sipAPIQtCore.h"
+
+
+// Construct a range and take a strong reference to the Python object.
+QPyAbstractRange::QPyAbstractRange(PyObject *data, bool editable) :
+ m_data(data), m_editable(editable)
+{
+ SIP_BLOCK_THREADS
+ Py_INCREF(m_data);
+ SIP_UNBLOCK_THREADS
+}
+
+
+// Destroy the range.
+QPyAbstractRange::~QPyAbstractRange()
+{
+ SIP_BLOCK_THREADS
+ Py_DECREF(m_data);
+ SIP_UNBLOCK_THREADS
+}
+
+
+// Raise a Python exception regarding the structure of the data.
+void QPyAbstractRange::raiseBadStructure()
+{
+ PyErr_SetString(PyExc_ValueError,
+ "the range data does not have the correct structure");
+}
+
+
+// Populate a 1D range from a Python list.
+bool QPyAbstractRange::populate1DFromList(QVariantList &range, PyObject *data)
+{
+ if (!PyList_Check(data))
+ {
+ raiseBadStructure();
+ return false;
+ }
+
+ Py_ssize_t size = PyList_Size(data);
+ if (size < 0)
+ return false;
+
+ for (Py_ssize_t i = 0; i < size; ++i)
+ {
+ PyObject *val = PyList_GetItem(data, i);
+ if (!val)
+ return false;
+
+ int is_err = 0;
+
+ QVariant qv = qpycore_PyObject_AsQVariant(val, &is_err);
+ Py_DECREF(val);
+
+ if (is_err)
+ return false;
+
+ range.append(qv);
+ }
+
+ return true;
+}
+
+
+// Populate a 1D range from a Python sequence.
+bool QPyAbstractRange::populate1DFromSequence(QVariantList &range,
+ PyObject *data)
+{
+ if (!PySequence_Check(data))
+ {
+ raiseBadStructure();
+ return false;
+ }
+
+ Py_ssize_t size = PySequence_Size(data);
+ if (size < 0)
+ return false;
+
+ for (Py_ssize_t i = 0; i < size; ++i)
+ {
+ PyObject *val = PySequence_GetItem(data, i);
+ if (!val)
+ return false;
+
+ int is_err = 0;
+
+ QVariant qv = qpycore_PyObject_AsQVariant(val, &is_err);
+ Py_DECREF(val);
+
+ if (is_err)
+ return false;
+
+ range.append(qv);
+ }
+
+ return true;
+}
+
+
+// Construct a sequence range.
+QPySequenceRange::QPySequenceRange(PyObject *data, bool editable) :
+ QPyAbstractRange(data, editable)
+{
+}
+
+
+// Create an appropriately configured QRangeModel for a sequence range. This
+// must be called with the GIL.
+sipQRangeModel *QPySequenceRange::create(QObject *parent)
+{
+ sipQRangeModel *model = nullptr;
+
+ if (editable())
+ {
+ if (populateFromList(m_seq_range, data()))
+ {
+ model = new sipQRangeModel(std::ref(m_seq_range), parent);
+ QObject::connect(model, &QRangeModel::dataChanged, this,
+ &QPySequenceRange::handleDataChanged);
+ }
+ }
+ else
+ {
+ if (populateFromSequence(m_seq_range, data()))
+ model = new sipQRangeModel(std::cref(m_seq_range), parent);
+ }
+
+ if (model)
+ setParent(model);
+
+ return model;
+};
+
+
+// Handle the dataChanged() signal for a sequence range.
+void QPySequenceRange::handleDataChanged(const QModelIndex &tl,
+ const QModelIndex &br)
+{
+ Q_UNUSED(br);
+
+ bool do_emit = false;
+
+ SIP_BLOCK_THREADS
+
+ // Note that we don't report any errors.
+ PyObject *py_data = qpycore_PyObject_FromQVariant(tl.data());
+ if (py_data)
+ do_emit = (PyList_SetItem(data(), tl.row(), py_data) == 0);
+
+ SIP_UNBLOCK_THREADS
+
+ // The signal must be emited without the GIL.
+ if (do_emit)
+ emit dataChanged(tl.row());
+}
+
+
+// Populate a sequence range from a Python list.
+bool QPySequenceRange::populateFromList(QVariantList &range, PyObject *data)
+{
+ bool ok = true;
+
+ SIP_BLOCK_THREADS
+ ok = populate1DFromList(range, data);
+ SIP_UNBLOCK_THREADS
+
+ return ok;
+}
+
+
+// Populate a sequence range from a Python sequence.
+bool QPySequenceRange::populateFromSequence(QVariantList &range,
+ PyObject *data)
+{
+ bool ok;
+
+ SIP_BLOCK_THREADS
+ ok = populate1DFromSequence(range, data);
+ SIP_UNBLOCK_THREADS
+
+ return ok;
+}
+
+
+// Construct a table range.
+QPyTableRange::QPyTableRange(PyObject *data, bool editable) :
+ QPyAbstractRange(data, editable)
+{
+}
+
+
+// Create an appropriately configured QRangeModel for a table range. This must
+// be called with the GIL.
+sipQRangeModel *QPyTableRange::create(QObject *parent)
+{
+ if (!populate(m_table_range, data()))
+ return nullptr;
+
+ sipQRangeModel *model;
+
+ if (editable())
+ {
+ model = new sipQRangeModel(std::ref(m_table_range), parent);
+ QObject::connect(model, &QRangeModel::dataChanged, this,
+ &QPyTableRange::handleDataChanged);
+ }
+ else
+ {
+ model = new sipQRangeModel(std::cref(m_table_range), parent);
+ }
+
+ setParent(model);
+
+ return model;
+};
+
+
+// Handle the dataChanged() signal for a table range.
+void QPyTableRange::handleDataChanged(const QModelIndex &tl,
+ const QModelIndex &br)
+{
+ Q_UNUSED(br);
+
+ bool do_emit = false;
+
+ SIP_BLOCK_THREADS
+
+ // Note that we don't report any errors.
+ PyObject *py_data = qpycore_PyObject_FromQVariant(tl.data());
+ if (py_data)
+ {
+ PyObject *row_data = PySequence_GetItem(data(), tl.row());
+
+ if (row_data != NULL)
+ {
+ do_emit = (PyList_SetItem(row_data, tl.column(), py_data) == 0);
+ Py_DECREF(row_data);
+ }
+ }
+
+ SIP_UNBLOCK_THREADS
+
+ // The signal must be emited without the GIL.
+ if (do_emit)
+ emit dataChanged(tl.row(), tl.column());
+}
+
+
+// Populate a table range.
+bool QPyTableRange::populate(QList<QVariantList> &range, PyObject *data)
+{
+ bool ok = true;
+
+ SIP_BLOCK_THREADS
+
+ if (PySequence_Check(data))
+ {
+ Py_ssize_t size = PySequence_Size(data);
+ if (size >= 0)
+ {
+ Py_ssize_t nr_cols = -1;
+
+ for (Py_ssize_t i = 0; i < size; ++i)
+ {
+ PyObject *val = PySequence_GetItem(data, i);
+ if (!val)
+ {
+ ok = false;
+ break;
+ }
+
+ QVariantList qvl;
+
+ if (editable())
+ ok = populate1DFromList(qvl, val);
+ else
+ ok = populate1DFromSequence(qvl, val);
+
+ Py_DECREF(val);
+
+ if (!ok)
+ break;
+
+ if (nr_cols < 0)
+ {
+ nr_cols = qvl.size();
+ }
+ else if (nr_cols != qvl.size())
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "the range data does not have the same number of columns in each row");
+ ok = false;
+ break;
+ }
+
+ range.append(qvl);
+ }
+ }
+ else
+ {
+ ok = false;
+ }
+ }
+ else
+ {
+ raiseBadStructure();
+ ok = false;
+ }
+
+ SIP_UNBLOCK_THREADS
+
+ return ok;
+}
+
+#endif
diff --git a/qpy/QtCore/qpycore_qrangemodel.h b/qpy/QtCore/qpycore_qrangemodel.h
new file mode 100644
index 0000000..aea4ee5
--- /dev/null
+++ b/qpy/QtCore/qpycore_qrangemodel.h
@@ -0,0 +1,128 @@
+// This is the interface support for QRangeModel.
+//
+// Copyright (c) 2025 Riverbank Computing Limited <info at riverbankcomputing.com>
+//
+// This file is part of PyQt6.
+//
+// This file may be used under the terms of the GNU General Public License
+// version 3.0 as published by the Free Software Foundation and appearing in
+// the file LICENSE included in the packaging of this file. Please review the
+// following information to ensure the GNU General Public License version 3.0
+// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+//
+// If you do not wish to use this file under the terms of the GPL version 3.0
+// then you may purchase a commercial license. For more information contact
+// info at riverbankcomputing.com.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+#ifndef _QPYCORE_QRANGEMODEL_H
+#define _QPYCORE_QRANGEMODEL_H
+
+#include <Python.h>
+
+#include <qglobal.h>
+
+#if QT_VERSION >= 0x060a00
+
+#include <qlist.h>
+#include <qobject.h>
+#include <qrangemodel.h>
+#include <qvariant.h>
+
+
+class sipQRangeModel;
+
+
+// The abstract base for classes that wrap a Python object to be used as an
+// appropriately configured range for use by QRangeModel.
+class QPyAbstractRange : public QObject
+{
+ Q_OBJECT
+
+public:
+ QPyAbstractRange(PyObject *data, bool editable);
+ virtual ~QPyAbstractRange();
+
+ PyObject *data() const
+ {
+#if PY_VERSION_HEX >= 0x030a0000
+ return Py_NewRef(m_data);
+#else
+ Py_INCREF(m_data);
+ return m_data;
+#endif
+ }
+
+ bool editable() const {return m_editable;}
+
+ // This is internal.
+ virtual sipQRangeModel *create(QObject *parent) = 0;
+
+protected:
+ // These are internal.
+ static void raiseBadStructure();
+ static bool populate1DFromList(QVariantList &range, PyObject *data);
+ static bool populate1DFromSequence(QVariantList &range, PyObject *data);
+
+private:
+ PyObject *m_data;
+ bool m_editable;
+};
+
+
+// A class that wraps a Python object to be used as an appropriately configured
+// sequence range for use by QRangeModel.
+class QPySequenceRange : public QPyAbstractRange
+{
+ Q_OBJECT
+
+public:
+ QPySequenceRange(PyObject *data, bool editable = false);
+
+ // This is internal.
+ sipQRangeModel *create(QObject *parent);
+
+signals:
+ void dataChanged(int index);
+
+private slots:
+ void handleDataChanged(const QModelIndex &tl, const QModelIndex &br);
+
+private:
+ QVariantList m_seq_range;
+
+ static bool populateFromList(QVariantList &range, PyObject *data);
+ static bool populateFromSequence(QVariantList &range, PyObject *data);
+};
+
+
+// A class that wraps a Python object to be used as an appropriately configured
+// table range for use by QRangeModel.
+class QPyTableRange : public QPyAbstractRange
+{
+ Q_OBJECT
+
+public:
+ QPyTableRange(PyObject *data, bool editable = false);
+
+ // This is internal.
+ sipQRangeModel *create(QObject *parent);
+
+signals:
+ void dataChanged(int row, int column);
+
+private slots:
+ void handleDataChanged(const QModelIndex &tl, const QModelIndex &br);
+
+private:
+ QList<QVariantList> m_table_range;
+
+ bool populate(QList<QVariantList> &range, PyObject *data);
+};
+
+#endif
+
+#endif
diff --git a/sip/QtCore/QtCoremod.sip b/sip/QtCore/QtCoremod.sip
index 060316f..8e4d24c 100644
--- a/sip/QtCore/QtCoremod.sip
+++ b/sip/QtCore/QtCoremod.sip
@@ -78,8 +78,8 @@ int PYQT_VERSION;
const char *PYQT_VERSION_STR;
%ModuleCode
-static int PYQT_VERSION = 0x060a00;
-static const char *PYQT_VERSION_STR = "6.10.0";
+static int PYQT_VERSION = 0x060a01;
+static const char *PYQT_VERSION_STR = "6.10.1";
%End
%Include qglobal.sip
@@ -214,6 +214,7 @@ static const char *PYQT_VERSION_STR = "6.10.0";
%Include qpycore_std_optional.sip
%Include qpycore_qset.sip
%Include qstringview.sip
+%Include qpycore_qrangemodel.sip
%Include qpycore_qlist.sip
%Include qwineventnotifier.sip
%Include qstringlist.sip
diff --git a/sip/QtCore/qobject.sip b/sip/QtCore/qobject.sip
index b1ae154..3b99f6a 100644
--- a/sip/QtCore/qobject.sip
+++ b/sip/QtCore/qobject.sip
@@ -255,10 +255,10 @@ static PyObject *qtcore_FindChildren(const QObject *parent, PyObject *types, con
sipTypeDef **type;
int yes, no;
} graph[] = {
- {sipName_QAbstractAnimation, &sipType_QAbstractAnimation, 23, 1},
+ {sipName_QAbstractAnimation, &sipType_QAbstractAnimation, 24, 1},
{sipName_QAbstractEventDispatcher, &sipType_QAbstractEventDispatcher, -1, 2},
- {sipName_QAbstractItemModel, &sipType_QAbstractItemModel, 29, 3},
- {sipName_QIODevice, &sipType_QIODevice, 37, 4},
+ {sipName_QAbstractItemModel, &sipType_QAbstractItemModel, 30, 3},
+ {sipName_QIODevice, &sipType_QIODevice, 39, 4},
{sipName_QCoreApplication, &sipType_QCoreApplication, -1, 5},
{sipName_QEventLoop, &sipType_QEventLoop, -1, 6},
{sipName_QFileSelector, &sipType_QFileSelector, -1, 7},
@@ -268,44 +268,64 @@ static PyObject *qtcore_FindChildren(const QObject *parent, PyObject *types, con
{sipName_QMimeData, &sipType_QMimeData, -1, 11},
{sipName_QObjectCleanupHandler, &sipType_QObjectCleanupHandler, -1, 12},
{sipName_QPluginLoader, &sipType_QPluginLoader, -1, 13},
- {sipName_QSettings, &sipType_QSettings, -1, 14},
- {sipName_QSharedMemory, &sipType_QSharedMemory, -1, 15},
- {sipName_QSignalMapper, &sipType_QSignalMapper, -1, 16},
- {sipName_QSocketNotifier, &sipType_QSocketNotifier, -1, 17},
- {sipName_QThread, &sipType_QThread, -1, 18},
- {sipName_QThreadPool, &sipType_QThreadPool, -1, 19},
- {sipName_QTimeLine, &sipType_QTimeLine, -1, 20},
- {sipName_QTimer, &sipType_QTimer, -1, 21},
- {sipName_QTranslator, &sipType_QTranslator, -1, 22},
+ #if QT_VERSION >= 0x060a00
+ {sipName_QPyAbstractRange, &sipType_QPyAbstractRange, 45, 14},
+ #else
+ {0, 0, 45, 14},
+ #endif
+ {sipName_QSettings, &sipType_QSettings, -1, 15},
+ {sipName_QSharedMemory, &sipType_QSharedMemory, -1, 16},
+ {sipName_QSignalMapper, &sipType_QSignalMapper, -1, 17},
+ {sipName_QSocketNotifier, &sipType_QSocketNotifier, -1, 18},
+ {sipName_QThread, &sipType_QThread, -1, 19},
+ {sipName_QThreadPool, &sipType_QThreadPool, -1, 20},
+ {sipName_QTimeLine, &sipType_QTimeLine, -1, 21},
+ {sipName_QTimer, &sipType_QTimer, -1, 22},
+ {sipName_QTranslator, &sipType_QTranslator, -1, 23},
#if defined(Q_OS_WIN)
{sipName_QWinEventNotifier, &sipType_QWinEventNotifier, -1, -1},
#else
{0, 0, -1, -1},
#endif
- {sipName_QAnimationGroup, &sipType_QAnimationGroup, 26, 24},
- {sipName_QPauseAnimation, &sipType_QPauseAnimation, -1, 25},
- {sipName_QVariantAnimation, &sipType_QVariantAnimation, 28, -1},
- {sipName_QParallelAnimationGroup, &sipType_QParallelAnimationGroup, -1, 27},
+ {sipName_QAnimationGroup, &sipType_QAnimationGroup, 27, 25},
+ {sipName_QPauseAnimation, &sipType_QPauseAnimation, -1, 26},
+ {sipName_QVariantAnimation, &sipType_QVariantAnimation, 29, -1},
+ {sipName_QParallelAnimationGroup, &sipType_QParallelAnimationGroup, -1, 28},
{sipName_QSequentialAnimationGroup, &sipType_QSequentialAnimationGroup, -1, -1},
{sipName_QPropertyAnimation, &sipType_QPropertyAnimation, -1, -1},
- {sipName_QAbstractListModel, &sipType_QAbstractListModel, 33, 30},
- {sipName_QAbstractProxyModel, &sipType_QAbstractProxyModel, 34, 31},
- {sipName_QAbstractTableModel, &sipType_QAbstractTableModel, -1, 32},
- {sipName_QConcatenateTablesProxyModel, &sipType_QConcatenateTablesProxyModel, -1, -1},
+ {sipName_QAbstractListModel, &sipType_QAbstractListModel, 35, 31},
+ {sipName_QAbstractProxyModel, &sipType_QAbstractProxyModel, 36, 32},
+ {sipName_QAbstractTableModel, &sipType_QAbstractTableModel, -1, 33},
+ {sipName_QConcatenateTablesProxyModel, &sipType_QConcatenateTablesProxyModel, -1, 34},
+ #if QT_VERSION >= 0x060a00
+ {sipName_QRangeModel, &sipType_QRangeModel, -1, -1},
+ #else
+ {0, 0, -1, -1},
+ #endif
{sipName_QStringListModel, &sipType_QStringListModel, -1, -1},
- {sipName_QIdentityProxyModel, &sipType_QIdentityProxyModel, -1, 35},
- {sipName_QSortFilterProxyModel, &sipType_QSortFilterProxyModel, -1, 36},
+ {sipName_QIdentityProxyModel, &sipType_QIdentityProxyModel, -1, 37},
+ {sipName_QSortFilterProxyModel, &sipType_QSortFilterProxyModel, -1, 38},
{sipName_QTransposeProxyModel, &sipType_QTransposeProxyModel, -1, -1},
- {sipName_QBuffer, &sipType_QBuffer, -1, 38},
- {sipName_QFileDevice, &sipType_QFileDevice, 40, 39},
+ {sipName_QBuffer, &sipType_QBuffer, -1, 40},
+ {sipName_QFileDevice, &sipType_QFileDevice, 42, 41},
#if !defined(QT_NO_PROCESS)
{sipName_QProcess, &sipType_QProcess, -1, -1},
#else
{0, 0, -1, -1},
#endif
- {sipName_QFile, &sipType_QFile, 42, 41},
+ {sipName_QFile, &sipType_QFile, 44, 43},
{sipName_QSaveFile, &sipType_QSaveFile, -1, -1},
{sipName_QTemporaryFile, &sipType_QTemporaryFile, -1, -1},
+ #if QT_VERSION >= 0x060a00
+ {sipName_QPySequenceRange, &sipType_QPySequenceRange, -1, 46},
+ #else
+ {0, 0, -1, 46},
+ #endif
+ #if QT_VERSION >= 0x060a00
+ {sipName_QPyTableRange, &sipType_QPyTableRange, -1, -1},
+ #else
+ {0, 0, -1, -1},
+ #endif
};
int i = 0;
diff --git a/sip/QtCore/qrangemodel.sip b/sip/QtCore/qpycore_qrangemodel.sip
similarity index 50%
copy from sip/QtCore/qrangemodel.sip
copy to sip/QtCore/qpycore_qrangemodel.sip
index 625b251..9ad84c4 100644
--- a/sip/QtCore/qrangemodel.sip
+++ b/sip/QtCore/qpycore_qrangemodel.sip
@@ -1,6 +1,4 @@
-// qrangemodel.sip generated by MetaSIP
-//
-// This file is part of the QtCore Python extension module.
+// This is the interface definition for the support for QRangeModel.
//
// Copyright (c) 2025 Riverbank Computing Limited <info at riverbankcomputing.com>
//
@@ -19,3 +17,49 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+%If (Qt_6_10_0 -)
+
+class QPyAbstractRange : public QObject /Abstract/
+{
+%TypeHeaderCode
+#include "qpycore_qrangemodel.h"
+%End
+
+public:
+ QPyAbstractRange(SIP_PYOBJECT data, bool editable);
+ virtual ~QPyAbstractRange();
+
+ SIP_PYOBJECT data() const;
+ bool editable() const;
+};
+
+
+class QPySequenceRange : public QPyAbstractRange
+{
+%TypeHeaderCode
+#include "qpycore_qrangemodel.h"
+%End
+
+public:
+ QPySequenceRange(SIP_PYOBJECT data, bool editable = false);
+
+signals:
+ void dataChanged(int index);
+};
+
+
+class QPyTableRange : public QPyAbstractRange
+{
+%TypeHeaderCode
+#include "qpycore_qrangemodel.h"
+%End
+
+public:
+ QPyTableRange(SIP_PYOBJECT data, bool editable = false);
+
+signals:
+ void dataChanged(int row, int column);
+};
+
+%End
diff --git a/sip/QtCore/qrangemodel.sip b/sip/QtCore/qrangemodel.sip
index 625b251..090bc5a 100644
--- a/sip/QtCore/qrangemodel.sip
+++ b/sip/QtCore/qrangemodel.sip
@@ -19,3 +19,79 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+%If (Qt_6_10_0 -)
+
+class QRangeModel : public QAbstractItemModel /ExportDerivedLocally/
+{
+%TypeHeaderCode
+#include <qrangemodel.h>
+#include "qpycore_qrangemodel.h"
+%End
+
+%TypeDerivedCode
+sipQRangeModel(const QVariantList &range, QObject *parent) : QRangeModel(range, parent) {}
+sipQRangeModel(QVariantList &range, QObject *parent) : QRangeModel(range, parent) {}
+sipQRangeModel(const QList<QVariantList> &range, QObject *parent) : QRangeModel(range, parent) {}
+sipQRangeModel(QList<QVariantList> &range, QObject *parent) : QRangeModel(range, parent) {}
+%End
+
+public:
+ QRangeModel(QPyAbstractRange *range /Transfer/, QObject *parent /TransferThis/ = 0) /HoldGIL, NoDerived/;
+%MethodCode
+ sipCpp = a0->create(a1);
+
+ if (!sipCpp)
+ sipError = sipErrorFail;
+%End
+
+ virtual ~QRangeModel();
+ QModelIndex index(int row, int column, const QModelIndex &parent = {}) const final;
+ QModelIndex parent(const QModelIndex &child) const final;
+ QModelIndex sibling(int row, int column, const QModelIndex &index) const final;
+ int rowCount(const QModelIndex &parent = {}) const final;
+ int columnCount(const QModelIndex &parent = {}) const final;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole);
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole);
+ virtual QMap<int, QVariant> itemData(const QModelIndex &index) const;
+ virtual bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &data);
+ virtual bool clearItemData(const QModelIndex &index);
+ bool insertColumns(int column, int count, const QModelIndex &parent = {}) final;
+ bool removeColumns(int column, int count, const QModelIndex &parent = {}) final;
+ bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destParent, int destColumn) final;
+ bool insertRows(int row, int count, const QModelIndex &parent = {}) final;
+ bool removeRows(int row, int count, const QModelIndex &parent = {}) final;
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destParent, int destRow) final;
+ virtual QHash<int, QByteArray> roleNames() const;
+ void setRoleNames(const QHash<int, QByteArray> &names);
+ void resetRoleNames();
+ virtual bool canFetchMore(const QModelIndex &parent) const;
+ virtual void fetchMore(const QModelIndex &parent);
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const final;
+ virtual QModelIndex buddy(const QModelIndex &index) const;
+ virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+ virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
+ virtual QStringList mimeTypes() const;
+ virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const;
+ virtual void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const;
+ virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ virtual QSize span(const QModelIndex &index) const;
+ virtual Qt::DropActions supportedDragActions() const;
+ virtual Qt::DropActions supportedDropActions() const;
+
+signals:
+ void roleNamesChanged();
+
+protected slots:
+ virtual void resetInternalData();
+
+protected:
+ virtual bool event(QEvent *);
+ virtual bool eventFilter(QObject *, QEvent *);
+};
+
+%End
diff --git a/sip/QtWidgets/qlineedit.sip b/sip/QtWidgets/qlineedit.sip
index 881c561..0d464fb 100644
--- a/sip/QtWidgets/qlineedit.sip
+++ b/sip/QtWidgets/qlineedit.sip
@@ -89,7 +89,7 @@ public:
void paste();
void deselect();
void insert(const QString &);
- QMenu *createStandardContextMenu() /Factory/;
+ QMenu *createStandardContextMenu() /Transfer/;
signals:
void textChanged(const QString &);
diff --git a/sip/QtWidgets/qplaintextedit.sip b/sip/QtWidgets/qplaintextedit.sip
index 3b31e9c..5930b42 100644
--- a/sip/QtWidgets/qplaintextedit.sip
+++ b/sip/QtWidgets/qplaintextedit.sip
@@ -67,8 +67,8 @@ public:
QString toPlainText() const;
void ensureCursorVisible();
virtual QVariant loadResource(int type, const QUrl &name);
- QMenu *createStandardContextMenu() /Factory/;
- QMenu *createStandardContextMenu(const QPoint &position) /Factory/;
+ QMenu *createStandardContextMenu() /Transfer/;
+ QMenu *createStandardContextMenu(const QPoint &position) /Transfer/;
QTextCursor cursorForPosition(const QPoint &pos) const;
QRect cursorRect(const QTextCursor &cursor) const;
QRect cursorRect() const;
@@ -138,7 +138,7 @@ public:
virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
protected:
- virtual QMimeData *createMimeDataFromSelection() const /Factory/;
+ virtual QMimeData *createMimeDataFromSelection() const /Transfer/;
virtual bool canInsertFromMimeData(const QMimeData *source) const;
virtual void insertFromMimeData(const QMimeData *source);
virtual void scrollContentsBy(int dx, int dy);
diff --git a/sip/QtWidgets/qscrollbar.sip b/sip/QtWidgets/qscrollbar.sip
index 9e60018..62001e9 100644
--- a/sip/QtWidgets/qscrollbar.sip
+++ b/sip/QtWidgets/qscrollbar.sip
@@ -46,6 +46,6 @@ protected:
public:
%If (Qt_6_10_0 -)
- QMenu *createStandardContextMenu(QPoint position) /Factory/;
+ QMenu *createStandardContextMenu(QPoint position) /Transfer/;
%End
};
diff --git a/sip/QtWidgets/qtextedit.sip b/sip/QtWidgets/qtextedit.sip
index 7919753..70dc9fd 100644
--- a/sip/QtWidgets/qtextedit.sip
+++ b/sip/QtWidgets/qtextedit.sip
@@ -93,8 +93,8 @@ public:
void append(const QString &text);
void ensureCursorVisible();
virtual QVariant loadResource(int type, const QUrl &name);
- QMenu *createStandardContextMenu() /Factory/;
- QMenu *createStandardContextMenu(const QPoint &position) /Factory/;
+ QMenu *createStandardContextMenu() /Transfer/;
+ QMenu *createStandardContextMenu(const QPoint &position) /Transfer/;
QTextCursor cursorForPosition(const QPoint &pos) const;
QRect cursorRect(const QTextCursor &cursor) const;
QRect cursorRect() const;
@@ -171,7 +171,7 @@ protected:
virtual void showEvent(QShowEvent *);
virtual void changeEvent(QEvent *e);
virtual void wheelEvent(QWheelEvent *e);
- virtual QMimeData *createMimeDataFromSelection() const /Factory/;
+ virtual QMimeData *createMimeDataFromSelection() const /Transfer/;
virtual bool canInsertFromMimeData(const QMimeData *source) const;
virtual void insertFromMimeData(const QMimeData *source);
virtual void inputMethodEvent(QInputMethodEvent *);
More information about the Neon-commits
mailing list