diff options
Diffstat (limited to 'sources/pyside6/PySide6/glue/qtwidgets.cpp')
-rw-r--r-- | sources/pyside6/PySide6/glue/qtwidgets.cpp | 141 |
1 files changed, 105 insertions, 36 deletions
diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp index f20b0d3ad..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 @@ -60,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 @@ -69,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 @@ -208,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(); @@ -239,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) { @@ -265,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); @@ -282,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)); @@ -299,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 { @@ -314,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); @@ -325,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); @@ -380,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); } @@ -429,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 @@ -503,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 @@ -607,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); } @@ -690,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; } @@ -740,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 ********************************************************************/ |