Как правильно завершить работу встроенного интерпретатора Python с использованием PyQt

Я пытаюсь создать программу на C ++ / Qt5, которая использует встроенный интерпретатор Python3 для сценариев и настройки.

Это мой подход:
Я создаю экземпляр QApplication в C ++, создаю экземпляр QMainwindow и добавляю QVBoxLayout и QPushbutton.

Затем я инициализирую интерпретатор Python, импортирую модуль python, содержащий некоторый базовый код PyQt для добавления второго QPushButton в QVBoxLayout, и выполняю этот код.

Затем, вернувшись в C ++, я вызываю ‘show ()’ для экземпляра QMainWindow и выполняю QApplication.

После возврата QApplication :: exec ()enter code heres, я пытаюсь очистить ссылки на PyObjects и пытаюсь завершить интерпретатор Python.

Зов Py_Finalize() вызывает ошибку сегментации.

Вот код:

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMainWindow>
#pragma push_macro("slots")
#undef slots
#include "Python.h"#pragma pop_macro("slots")

int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;// Initialize QApplication and setup basic widgets.
QApplication app (argc, argv);
QMainWindow mainWindow (nullptr);
QPushButton button ("test", &mainWindow);
QWidget * widget = new QWidget(&mainWindow);
mainWindow.setCentralWidget(widget);
auto l = new QVBoxLayout ();
widget->setLayout(l);
l->addWidget(&button);

// Initialize the Python Interpreter
Py_Initialize();// Build the name object
pName = PyUnicode_FromString("runPyQt");

// Load the module object
pModule = PyImport_Import(pName);

if (!pModule){
Py_Finalize();
return 1;
}

pDict = PyModule_GetDict(pModule);

pFunc = PyDict_GetItemString(pDict, "main");

if (PyCallable_Check(pFunc))
{
PyObject_CallObject(pFunc, nullptr);
} else
{
PyErr_Print();
}

mainWindow.show();

int r = 0;

r = QApplication::exec();

// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);

// Finish the Python Interpreter
Py_Finalize();

return r;
}

И модуль Python:

import sys
if sys.platform.startswith( 'linux' ) :
from OpenGL import GL

from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindowdef main():
app = QApplication.instance()
widgets = app.topLevelWidgets()
for widget in widgets:
if type(widget) is QMainWindow:
break
widget = widget.centralWidget()

widget.layout().addWidget(QPushButton('Hello from PyQt'))

Я предположил, что это как-то связано с отсутствием GIL при финализации интерпретатора. Я пробовал звонить PyEval_AcquireLock() прямо перед финализацией, что приводит к зависанию программы в этой точке.

Возможно, PyQt где-то получает блокировку и не снимает ее до завершения, но это только предположение.

До вызова Py_Finalize() программа работает именно так, как я ожидаю. Даже использование PyQt для добавления некоторых нетривиальных виджетов работает нормально.

Мой вопрос: как мне правильно завершить интерпретатор Python в этой ситуации?

3

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]