diff options
Diffstat (limited to 'sources/pyside6/plugins/uitools')
-rw-r--r-- | sources/pyside6/plugins/uitools/CMakeLists.txt | 35 | ||||
-rw-r--r-- | sources/pyside6/plugins/uitools/customwidget.cpp | 104 | ||||
-rw-r--r-- | sources/pyside6/plugins/uitools/customwidget.h | 37 | ||||
-rw-r--r-- | sources/pyside6/plugins/uitools/customwidgets.cpp | 25 | ||||
-rw-r--r-- | sources/pyside6/plugins/uitools/customwidgets.h | 35 |
5 files changed, 236 insertions, 0 deletions
diff --git a/sources/pyside6/plugins/uitools/CMakeLists.txt b/sources/pyside6/plugins/uitools/CMakeLists.txt new file mode 100644 index 000000000..06d0ae900 --- /dev/null +++ b/sources/pyside6/plugins/uitools/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +project(plugins) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt6 COMPONENTS Core Gui Widgets UiPlugin) + +set(ui_plugin_src + customwidgets.cpp customwidgets.h + customwidget.cpp customwidget.h +) + +add_library(uiplugin STATIC ${ui_plugin_src}) +if(CMAKE_HOST_UNIX AND NOT CYGWIN) + add_definitions(-fPIC) +endif() +add_definitions(-DQT_STATICPLUGIN) + +set_property(TARGET pyside6 PROPERTY CXX_STANDARD 17) + +target_link_libraries(uiplugin + Qt::Core + Qt::Gui + Qt::UiPlugin + Qt::Widgets + Shiboken6::libshiboken) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX}) +else() + set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_RELEASE_POSTFIX}) +endif() diff --git a/sources/pyside6/plugins/uitools/customwidget.cpp b/sources/pyside6/plugins/uitools/customwidget.cpp new file mode 100644 index 000000000..976754feb --- /dev/null +++ b/sources/pyside6/plugins/uitools/customwidget.cpp @@ -0,0 +1,104 @@ +// Copyright (C) 2020 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 + +#include "customwidget.h" +#include <QtCore/qdebug.h> + +// Part of the static plugin linked to the QtUiLoader Python module, +// allowing it to create a custom widget written in Python. +PyCustomWidget::PyCustomWidget(PyObject *objectType) : + m_pyObject(objectType), + m_name(QString::fromUtf8(reinterpret_cast<PyTypeObject *>(objectType)->tp_name)) +{ +} + +bool PyCustomWidget::isContainer() const +{ + return false; +} + +bool PyCustomWidget::isInitialized() const +{ + return m_initialized; +} + +QIcon PyCustomWidget::icon() const +{ + return {}; +} + +QString PyCustomWidget::domXml() const +{ + return {}; +} + +QString PyCustomWidget::group() const +{ + return {}; +} + +QString PyCustomWidget::includeFile() const +{ + return {}; +} + +QString PyCustomWidget::name() const +{ + return m_name; +} + +QString PyCustomWidget::toolTip() const +{ + return {}; +} + +QString PyCustomWidget::whatsThis() const +{ + return {}; +} + +// A copy of this code exists in PyDesignerCustomWidget::createWidget() +// (see sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp). +QWidget *PyCustomWidget::createWidget(QWidget *parent) +{ + // Create a python instance and return cpp object + PyObject *pyParent = nullptr; + bool unknownParent = false; + if (parent != nullptr) { + pyParent = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(parent)); + if (pyParent != nullptr) { + Py_INCREF(pyParent); + } else { + static Shiboken::Conversions::SpecificConverter converter("QWidget*"); + pyParent = converter.toPython(&parent); + unknownParent = true; + } + } else { + Py_INCREF(Py_None); + pyParent = Py_None; + } + + Shiboken::AutoDecRef pyArgs(PyTuple_New(1)); + PyTuple_SET_ITEM(pyArgs.object(), 0, pyParent); // tuple will keep pyParent reference + + // Call python constructor + auto *result = reinterpret_cast<SbkObject *>(PyObject_CallObject(m_pyObject, pyArgs)); + if (result == nullptr) { + qWarning("Unable to create a Python custom widget of type \"%s\".", + qPrintable(m_name)); + PyErr_Print(); + return nullptr; + } + + if (unknownParent) // if parent does not exist in python, transfer the ownership to cpp + Shiboken::Object::releaseOwnership(result); + else + Shiboken::Object::setParent(pyParent, reinterpret_cast<PyObject *>(result)); + + return reinterpret_cast<QWidget *>(Shiboken::Object::cppPointer(result, Py_TYPE(result))); +} + +void PyCustomWidget::initialize(QDesignerFormEditorInterface *) +{ + m_initialized = true; +} diff --git a/sources/pyside6/plugins/uitools/customwidget.h b/sources/pyside6/plugins/uitools/customwidget.h new file mode 100644 index 000000000..52621f0bd --- /dev/null +++ b/sources/pyside6/plugins/uitools/customwidget.h @@ -0,0 +1,37 @@ +// Copyright (C) 2020 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 + +#ifndef PY_CUSTOM_WIDGET_H_ +#define PY_CUSTOM_WIDGET_H_ + +#include <shiboken.h> + +#include <QtUiPlugin/QDesignerCustomWidgetInterface> + +class PyCustomWidget: public QObject, public QDesignerCustomWidgetInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + explicit PyCustomWidget(PyObject *objectType); + + bool isContainer() const override; + bool isInitialized() const override; + QIcon icon() const override; + QString domXml() const override; + QString group() const override; + QString includeFile() const override; + QString name() const override; + QString toolTip() const override; + QString whatsThis() const override; + QWidget *createWidget(QWidget *parent) override; + void initialize(QDesignerFormEditorInterface *core) override; + +private: + PyObject *m_pyObject = nullptr; + const QString m_name; + bool m_initialized = false; +}; + +#endif // PY_CUSTOM_WIDGET_H_ diff --git a/sources/pyside6/plugins/uitools/customwidgets.cpp b/sources/pyside6/plugins/uitools/customwidgets.cpp new file mode 100644 index 000000000..93b6b4a10 --- /dev/null +++ b/sources/pyside6/plugins/uitools/customwidgets.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2020 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 + +#include "customwidgets.h" +#include "customwidget.h" + +PyCustomWidgets::PyCustomWidgets(QObject *parent) + : QObject(parent) +{ +} + +PyCustomWidgets::~PyCustomWidgets() +{ + qDeleteAll(m_widgets); +} + +void PyCustomWidgets::registerWidgetType(PyObject *widget) +{ + m_widgets.append(new PyCustomWidget(widget)); +} + +QList<QDesignerCustomWidgetInterface *> PyCustomWidgets::customWidgets() const +{ + return m_widgets; +} diff --git a/sources/pyside6/plugins/uitools/customwidgets.h b/sources/pyside6/plugins/uitools/customwidgets.h new file mode 100644 index 000000000..f67a0847d --- /dev/null +++ b/sources/pyside6/plugins/uitools/customwidgets.h @@ -0,0 +1,35 @@ +// Copyright (C) 2020 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 + +#ifndef PY_CUSTOM_WIDGETS_H_ +#define PY_CUSTOM_WIDGETS_H_ + +#include <shiboken.h> + +#include <QtUiPlugin/QDesignerCustomWidgetInterface> + +#include <QtCore/qlist.h> + +// A static plugin linked to the QtUiLoader Python module +class PyCustomWidgets: public QObject, public QDesignerCustomWidgetCollectionInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.PySide.PyCustomWidgetsInterface") + +public: + Q_DISABLE_COPY_MOVE(PyCustomWidgets) + + explicit PyCustomWidgets(QObject *parent = nullptr); + ~PyCustomWidgets() override; + + QList<QDesignerCustomWidgetInterface*> customWidgets() const override; + + // Called from added function QUiLoader::registerCustomWidget() + void registerWidgetType(PyObject* widget); + +private: + QList<QDesignerCustomWidgetInterface *> m_widgets; +}; + +#endif |