Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide2 embedded in C++ application only has QCoreApplication instead of full QApplication

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

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 2 Posters 753 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wrosecrans
    wrote on last edited by
    #1

    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?

    jsulmJ 1 Reply Last reply
    0
    • W wrosecrans

      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?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

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

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved