How to embed python interpreter that can use PySide2 to interact with widgets created in C++?
Unsolved
Qt for Python
-
Hello,
I am creating a python plugin system for my Qt5 C++ application. I'm using pybind11 to embed the python interpreter into my app. I would like plugins to be able to add custom PySide2 widgets to already existing C++ widgets. While doing that, I have to respect the following requirements:- No dependencies other than PySide2 or PyQt5 (prefer the former) on the python side, and no linking to additional libraries besides pybind11 and the libpython library
- No binding generation using shiboken, though I'm willing to accept shiboken as a dependency if need be
- No converting parts of my application into a standalone library
I have managed to create a QApplication in C++ and it is available inside python, so I can add top-level widgets to my application just fine. But I don't know how my python module can interact with widgets created in C++.
Here's an example application to illustrate what I want:
- In C++ I create a window, set a vbox layout and add a button to the layout.
- I import a custom module called mymodule using the embedded interpreter, thereby executing the module
- mymodule creates a PySide2 QPushButton and adds it to the layout that was created on the C++ side
C++ code (main.cpp):
#include <pybind11/embed.h> #include <QApplication> #include <QPushButton> #include <QVBoxLayout> #include <QWidget> namespace py = pybind11; int main(int argc, char* argv[]) { py::scoped_interpreter guard{}; QApplication app(argc, argv); auto window = new QWidget(); auto cppButton = new QPushButton("C++ button"); auto layout = new QVBoxLayout(window); layout->addWidget(cppButton); window->show(); // Executes mymodule in the current directory auto module = py::module_::import("mymodule"); return app.exec(); }
Python code in ./mymodule.py:
from PySide2.QtWidgets import QPushButton pythonButton = QPushButton('Python button') # How can I obtain a reference to 'layout' that was created in C++, so the following is possible: layout.addWidget(pythonButton)
Is what I'm asking even possible?
-
Hi,
I think you will be interested by the scriptable application example in PySide's sources.