将 PySide/PyQt 小部件嵌入到 Qt/C++ 应用程序中

问题描述 投票:0回答:3

我有一个 C++/Qt 应用程序,它的 GUI 应该可以通过模块进行扩展。扩展应该简单且通用。我只是在检查一个概念 - 是否有可能让这个主要的 C++/Qt 应用程序执行一个 Python/PySide/PyQt 脚本,该脚本将创建一个 QWidget(或派生类)实例并将这个小部件嵌入到主要的 C++/Qt 应用程序中?

是否有任何工作片段可以证明此任务的可行性? IE。如何创建和嵌入小部件?如何在应用程序和小部件之间传递信号?

qt pyqt pyside
3个回答
9
投票

这个问题有点老了,但是如果其他人面临同样的问题,我会尽力给出有用的答案。

我认为这是可能的。在下面的示例中,我用 c++ 创建了 QApplication 和 QMainWindow,嵌入了 python 解释器,然后在 python 端创建了一个 QPushButton,并将其添加到主窗口中。

试试这个:

#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();
}

Python 脚本是用字符串编写的,以便将所有内容都放在一个文件中,但您当然可以从 .py 文件中读取它。

对象所有权可能是一个问题,如 Trilarion 给出的链接所示。


2
投票

我认为这是不可能的。 PySide/PyQt 是 C++/Qt 的包装器。这意味着您创建 C++ 对象和 Python 包装器对象,并且包装器对象以某种方式引用 C++ 对象。据我所知,这是一种有效的方法。

但你想要另一种方式。基本上是 Python 对象的包装器(Python 对象本身是 C++ 对象的包装器)以在 C++ 中使用。我认为 PySide/PyQt 还没有为此做好准备。但是,可以将 Python 嵌入其他语言

另请参阅如何搬起石头砸自己的脚。有关 C++/Qt 和 Python 之间通信的陷阱。


0
投票

这里改编为QT5版本的Francois回答:

#include "Python.h"
#include <QApplication>
#include <QMainWindow>

#include <iostream>

class PythonQt
{

public:

  PythonQt()
  {
    Py_SetProgramName(L"/path/to/executable");
    Py_SetPythonHome(L"/path/to/python-home");
    Py_IgnoreEnvironmentFlag = true;
    Py_Initialize();

    std::string code =
        "import sys\n"
        "print(sys.path)\n"
        "from PySide2 import QtGui\n"
        "from PySide2 import QtWidgets\n"
        ""
        "all_widgets = QtWidgets.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"
        "    QtWidgets.QMessageBox.information(None, 'Test', 'Hello!', \
                      QtWidgets.QMessageBox.Ok)\n"
        "    QtWidgets.QApplication.instance().quit()\n"
        ""
        "button = QtWidgets.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();
}
© www.soinside.com 2019 - 2024. All rights reserved.