aboutsummaryrefslogtreecommitdiff
path: root/libs/plugin_python/tests/python/test_qt_widgets.cpp
blob: 6d8a9019b1e59c183f116cd9ffc2cdf0cdd8d275 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "pybind11_qt/pybind11_qt.h"

#include <pybind11/pybind11.h>

#include <QMap>
#include <QWidget>

namespace py = pybind11;
using namespace pybind11::literals;

QMap<QString, QWidget*> s_Widgets;
QWidget* s_Parent;

class CustomWidget : public QWidget {
public:
    CustomWidget(QString const& name, QWidget* parent = nullptr) : QWidget(parent)
    {
        s_Widgets[name] = this;
        setProperty("name", name);
    }

    ~CustomWidget() { s_Widgets.remove(property("name").toString()); }
};

class PyCustomWidget : public CustomWidget {
public:
    using CustomWidget::CustomWidget;
    int heightForWidth(int value) const
    {
        PYBIND11_OVERRIDE(int, CustomWidget, heightForWidth, value);
    }
};

PYBIND11_MODULE(qt_widgets, m)
{
    s_Parent = new QWidget();

    py::class_<CustomWidget, PyCustomWidget, py::qt::qobject_holder<CustomWidget>>
        pyCustomWidget(m, "CustomWidget");
    pyCustomWidget
        .def(py::init<QString, QWidget*>(), "name"_a, "parent"_a = (QWidget*)nullptr)
        .def("set_parent_cpp", [](CustomWidget* w) {
            w->setParent(s_Parent);
        });
    py::qt::add_qt_delegate<QWidget>(pyCustomWidget, "_widget");

    m.def("is_alive", [](QString const& name) {
        return s_Widgets.contains(name);
    });

    m.def("get", [](QString const& name) {
        return s_Widgets.contains(name) ? s_Widgets[name] : nullptr;
    });

    m.def("set_parent", [](QWidget* widget) {
        widget->setParent(s_Parent);
    });

    m.def("is_owned_cpp", [](QString const& name) {
        return s_Widgets.contains(name) && s_Widgets[name]->parent() == s_Parent;
    });

    m.def("make_widget_own_cpp", [](QString const& name) -> QWidget* {
        return new CustomWidget(name, s_Parent);
    });

    m.def(
        "make_widget_own_py",
        [](QString const& name) -> QWidget* {
            return new CustomWidget(name);
        },
        py::return_value_policy::take_ownership);

    // simply passing the widget gives the ownership of the Python object to C++
    m.def("send_to_cpp", [](QString const& name, QWidget* widget) {
        widget->setProperty("name", name);
        widget->setParent(s_Parent);
        s_Widgets[name] = widget;
    });

    m.def("heightForWidth", [](QString const& name, int value) {
        return s_Widgets.contains(name) ? s_Widgets[name]->heightForWidth(value)
                                        : -1024;
    });
}