diff options
Diffstat (limited to 'sources/pyside6/PySide6/glue/qtwidgets.cpp')
-rw-r--r-- | sources/pyside6/PySide6/glue/qtwidgets.cpp | 181 |
1 files changed, 107 insertions, 74 deletions
diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp index b355f41cb..f886106cf 100644 --- a/sources/pyside6/PySide6/glue/qtwidgets.cpp +++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 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 @@ -56,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 @@ -96,6 +61,11 @@ QFormLayout::ItemRole _role; %CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role); %PYARG_0 = PyTuple_New(2); PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row)); +// On the C++ side, *rolePtr is not set if row == -1, in which case on +// the Python side this gets converted to a random value outside the +// enum range. Fix this by setting _role to a default value here. +if (_row == -1) + _role = QFormLayout::LabelRole; PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role)); // @snippet qformlayout-fix-args @@ -105,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 @@ -244,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(); @@ -275,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) { @@ -301,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); @@ -318,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)); @@ -335,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 { @@ -350,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); @@ -361,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); @@ -416,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); } @@ -465,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 @@ -539,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 @@ -643,7 +656,7 @@ for (auto *act : actions) { } %CPPSELF.clear(); -for (auto *obj : qAsConst(lst)) { +for (auto *obj : std::as_const(lst)) { Shiboken::Object::invalidate(reinterpret_cast<SbkObject *>(obj)); Py_XDECREF(obj); } @@ -726,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; } @@ -776,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 ********************************************************************/ |