Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

PySide2 embedded in C++ application only has QCoreApplication instead of full QApplication



  • So, basically, my question is, how can I find widgets created in C++, when I am using Python embedded in a C++ Application. I made an example of what I am talking about...

    #include <pybind11/embed.h> // everything needed for embedding
    
    #include <iostream>
    #include <QWidget>
    #include <QApplication>
    
    namespace py = pybind11;
    
    void pystuff() {
    
        py::print("Hello, from Python!"); // use the Python API
        py::exec("import PySide2");
        py::exec("from PySide2 import QtWidgets");
        py::exec("app = QtWidgets.QApplication.instance()");
    
        py::exec("print(type(app))");
        py::exec("import sys");
        py::exec("print(sys.version)");
        py::exec("print(PySide2.__version__)");
        py::exec("w = QtWidgets.QWidget()");
        py::exec("w.show(); w.setWindowTitle('Python')");
        py::exec("print('', flush=True)");
    
    }
    
    int main(int argc, char *argv[])
    {
        QApplication *a = new QApplication(argc, argv);
        py::scoped_interpreter guard{}; // start the interpreter and keep it alive
    
        QWidget w;
        w.setWindowTitle("C++");
        w.show();
    
        a->connect(a, &QGuiApplication::applicationStateChanged, [a](Qt::ApplicationState state) {
            if (state == Qt::ApplicationActive) {
                pystuff();
                std::cout << "Checking all Widgets..." << std::endl;
                for (auto && widget : a->allWidgets() ) {
                    std::cout << widget->windowTitle().toStdString() << std::endl;
                }
            }
        });
    
        return a->exec();
    }
    

    The result of this is that I have created two windows. One window was created in C++. The other was created using Python. That much works. After I run the python, in C++ I iterate over "QApplication->allWidgets() " and I can see the widget I created in Python, so I could theoretically add it to a layout or whatever in C++. But, I can't do the reverse because the type of py::exec("app = QtWidgets.QApplication.instance()");
    is just a QCoreApplication instead of a full QApplication object. So it has no allWidgets() method for me to interrogate. Which is super confusing. Here's the output:

    Hello, from Python!
    <class 'PySide2.QtCore.QCoreApplication'>
    3.7.5 (default, Nov  1 2019, 02:16:32) 
    [Clang 11.0.0 (clang-1100.0.33.8)]
    5.12.5a1.dev1566934103
    
    Checking all Widgets...
    Python
    C++
    

    WTF?


  • Lifetime Qt Champion

    @wrosecrans Did you try to cast app to QApplication? QApplication inderectly inherits QCoreApplication.
    instance() returns pointer to QCoreApplication according to Qt documentation.


Log in to reply