Search code examples
qtpyqtpyside

Embeding PySide/PyQt widget into Qt/C++ application


I have a C++/Qt application which should have its GUI extensible with modules. Extending should be simple and versatile. I am just checking a concept - is it possible to have this main C++/Qt application that would execute a Python/PySide/PyQt script which would create a QWidget (or derived class) instance and embed this widget into the main C++/Qt application?

Is there any working snippet to demonstrate the feasibility of this task? I.e. how to create and embed the widget? How to pass signals between the application and the widget?


Solution

  • This question is a bit old, but in case someone else is face the same issue, I will try to give a useful answer.

    I think it's possible. In the following example, I create a QApplication and QMainWindow in c++, embed a python interpreter, and then, on the python side, I create a QPushButton which I add to the main window.

    Try this out:

    #include <QApplication>
    #include <QMainWindow>
    
    #include <iostream>
    #include "Python.h"
    
    class PythonQt
    {
    
    public:
    
      PythonQt()
      {
        char name[] = "test";
        Py_SetProgramName(name);
        Py_Initialize();
    
        std::string code =
            "from PySide import QtGui\n"
            ""
            "all_widgets = QtGui.QApplication.instance().allWidgets()\n"
            "window = None\n"
            "for widget in all_widgets:\n"
            "    if str(widget.objectName()) == \"main_window\":\n"
            "      window = widget\n"
            "      break\n"
            ""
            "def message_box():\n"
            "    QtGui.QMessageBox.information(None, 'Test', 'Hello!', \ 
                          QtGui.QMessageBox.Ok)\n"
            "    QtGui.QApplication.instance().quit()\n"
            ""
            "button = QtGui.QPushButton('Press Me')\n"
            "button.clicked.connect(message_box)\n"
            "window.setCentralWidget(button)\n"
            "window.move(600, 300)\n"
            "window.show()";
    
        PyRun_SimpleString(code.c_str());
      }
    
    };
    
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
      QMainWindow win;
      win.setObjectName("main_window");
    
      PythonQt python_code;
    
      a.exec();
    }
    

    The python script is written here in a string to have everything in a single file, but you could of course read it in from a .py file.

    Object ownership could be an issue though, as shown in the link given by Trilarion.