Advices on embedding python in Qt/C++ application

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Advices on embedding python in Qt/C++ application

Andrew Cunningham
Alexis,
You may want to look at PythonQT as a way to integrate python into a C++ application.
It happily co-exists with PyQT. Just make sure you are using the same QT version....

Andrew

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Alexis Barbot
Thanks for these replies,

First of all, I had a look at PythonQt which indeed looked promising in my case. However I had toubles to build it, so I skipped that solution. Now I understand that this was probably caused by the compilation attempt with mingw while using a binary python installer, obviously compiled using msvc.
Furthermore, I got some success with PyQt: after preparing all paths and adding several flags to the configure command, I could perform the complete build wihtout errors. I so tried to write a small piece of code to validate my usage. It builds correctly, but it suddenly stop while running without any error message. Here is the code:

```
#include <QDebug>
#include <Python.h>
#include <QDateTime>
#include <sipAPIQtCore.h>
#include <memory>

int main(int argc, char* argv[])
{
    qDebug() << "start";
    Py_Initialize();
    auto d = PyDict_New();
    auto test = std::make_unique<QDateTime>();
    auto pyTest = sipConvertFromType(test.get(), sipType_QDateTime, nullptr);
    qDebug() << "end";
    Py_FinalizeEx();
    return 0;
}
```

It sounds like everything is installed but I'm missing some initialization step. Is that possible? Or maybe there's something else I should check/try?
Many thanks for your help.

Alexis


Le lun. 26 août 2019 à 18:35, Andrew Cunningham <[hidden email]> a écrit :
Alexis,
You may want to look at PythonQT as a way to integrate python into a C++ application.
It happily co-exists with PyQT. Just make sure you are using the same QT version....

Andrew

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Phil Thompson-5
On 27/08/2019 08:29, Alexis Barbot wrote:

> Thanks for these replies,
>
> First of all, I had a look at PythonQt which indeed looked promising in
> my
> case. However I had toubles to build it, so I skipped that solution.
> Now I
> understand that this was probably caused by the compilation attempt
> with
> mingw while using a binary python installer, obviously compiled using
> msvc.
> Furthermore, I got some success with PyQt: after preparing all paths
> and
> adding several flags to the configure command, I could perform the
> complete
> build wihtout errors. I so tried to write a small piece of code to
> validate
> my usage. It builds correctly, but it suddenly stop while running
> without
> any error message. Here is the code:
>
> ```
> #include <QDebug>
> #include <Python.h>
> #include <QDateTime>
> #include <sipAPIQtCore.h>
> #include <memory>
>
> int main(int argc, char* argv[])
> {
>     qDebug() << "start";
>     Py_Initialize();
>     auto d = PyDict_New();
>     auto test = std::make_unique<QDateTime>();
>     auto pyTest = sipConvertFromType(test.get(), sipType_QDateTime,
> nullptr);
>     qDebug() << "end";
>     Py_FinalizeEx();
>     return 0;
> }
> ```
>
> It sounds like everything is installed but I'm missing some
> initialization
> step. Is that possible? Or maybe there's something else I should
> check/try?
> Many thanks for your help.

You haven't imported PyQt5.QtCore.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Alexis Barbot
What do you mean? Should I import this module in the python context? I tried adding this line wihtout any effect:
`PyRun_SimpleString("import PyQt5.QtCore")`

If we're speaking about some cpp header to include, I can't see which one it is.
Thanks

Le mar. 27 août 2019 à 10:25, Phil Thompson <[hidden email]> a écrit :
On 27/08/2019 08:29, Alexis Barbot wrote:
> Thanks for these replies,
>
> First of all, I had a look at PythonQt which indeed looked promising in
> my
> case. However I had toubles to build it, so I skipped that solution.
> Now I
> understand that this was probably caused by the compilation attempt
> with
> mingw while using a binary python installer, obviously compiled using
> msvc.
> Furthermore, I got some success with PyQt: after preparing all paths
> and
> adding several flags to the configure command, I could perform the
> complete
> build wihtout errors. I so tried to write a small piece of code to
> validate
> my usage. It builds correctly, but it suddenly stop while running
> without
> any error message. Here is the code:
>
> ```
> #include <QDebug>
> #include <Python.h>
> #include <QDateTime>
> #include <sipAPIQtCore.h>
> #include <memory>
>
> int main(int argc, char* argv[])
> {
>     qDebug() << "start";
>     Py_Initialize();
>     auto d = PyDict_New();
>     auto test = std::make_unique<QDateTime>();
>     auto pyTest = sipConvertFromType(test.get(), sipType_QDateTime,
> nullptr);
>     qDebug() << "end";
>     Py_FinalizeEx();
>     return 0;
> }
> ```
>
> It sounds like everything is installed but I'm missing some
> initialization
> step. Is that possible? Or maybe there's something else I should
> check/try?
> Many thanks for your help.

You haven't imported PyQt5.QtCore.

Phil

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Phil Thompson-5
Have you read this...

https://www.riverbankcomputing.com/static/Docs/sip/embedding.html

On 27/08/2019 09:45, Alexis Barbot wrote:

> What do you mean? Should I import this module in the python context? I
> tried adding this line wihtout any effect:
> `PyRun_SimpleString("import PyQt5.QtCore")`
>
> If we're speaking about some cpp header to include, I can't see which
> one
> it is.
> Thanks
>
> Le mar. 27 août 2019 à 10:25, Phil Thompson
> <[hidden email]> a
> écrit :
>
>> On 27/08/2019 08:29, Alexis Barbot wrote:
>> > Thanks for these replies,
>> >
>> > First of all, I had a look at PythonQt which indeed looked promising in
>> > my
>> > case. However I had toubles to build it, so I skipped that solution.
>> > Now I
>> > understand that this was probably caused by the compilation attempt
>> > with
>> > mingw while using a binary python installer, obviously compiled using
>> > msvc.
>> > Furthermore, I got some success with PyQt: after preparing all paths
>> > and
>> > adding several flags to the configure command, I could perform the
>> > complete
>> > build wihtout errors. I so tried to write a small piece of code to
>> > validate
>> > my usage. It builds correctly, but it suddenly stop while running
>> > without
>> > any error message. Here is the code:
>> >
>> > ```
>> > #include <QDebug>
>> > #include <Python.h>
>> > #include <QDateTime>
>> > #include <sipAPIQtCore.h>
>> > #include <memory>
>> >
>> > int main(int argc, char* argv[])
>> > {
>> >     qDebug() << "start";
>> >     Py_Initialize();
>> >     auto d = PyDict_New();
>> >     auto test = std::make_unique<QDateTime>();
>> >     auto pyTest = sipConvertFromType(test.get(), sipType_QDateTime,
>> > nullptr);
>> >     qDebug() << "end";
>> >     Py_FinalizeEx();
>> >     return 0;
>> > }
>> > ```
>> >
>> > It sounds like everything is installed but I'm missing some
>> > initialization
>> > step. Is that possible? Or maybe there's something else I should
>> > check/try?
>> > Many thanks for your help.
>>
>> You haven't imported PyQt5.QtCore.
>>
>> Phil
>>
>
> _______________________________________________
> PyQt mailing list    [hidden email]
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Alexis Barbot
I looked at it, but it seems I didn't catch the point (or possibly the moment I read it I did not figure out it could be what I needed...). I now understand that it explains I should get the c api dynamically to call it, whereas I was trying to call static method. I could get something roughtly working this way, with pyqt compiled in static (see code below). I'm currently trying to clean everythind, but I realized I had to upgrade Qt for that, as I can't find a PyQt package for Qt5.9 (sad, as it's a LTS). So I'll keep you updated on my progress.
In my tests I realized something: is there some special care to do with containers while passing from C++/python? In my first attemp to pass a QVariantMap the items added after SetItem to python are not visible from python? (and items modified in python are not modified in c++). Any special thoughts about this?
Thanks for all your help

Alexis

```
Py_Initialize();
PyEval_InitThreads();
auto sipModule = PyImport_ImportModule("sip");
PyImport_ImportModule("PyQt5.sip");
auto sipAPI = (const sipAPIDef*)PyCapsule_Import("sip._C_API", 0);
PyCapsule_Import("PyQt5.QtCore._C_API", 0);
auto sipModuleDict = PyModule_GetDict(sipModule);
auto sip_sipmod = PyImport_ImportModule("PyQt5.sip");
auto sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod), "_C_API");

sipAPI_QtCore = reinterpret_cast<const sipAPIDef*>(PyCapsule_GetPointer(sip_capiobj, "PyQt5.sip._C_API"));
qpycore_init();
sipExportModule(&sipModuleAPI_QtCore, SIP_API_MAJOR_NR, SIP_API,MINOR_NR, 0);

auto m = PyImport_AddModule("__main__");
auto g = PyModule_GetDict(m);
auto d = PyDictNew();

auto test = std::make_unique<QDateTIme>(QDateTIme::currentDateTime);
auto type = sipAPI_QtCore->api_find_type("QDateTime);
auto pyTest = sipAPI_QtCore->api_convert_from_type(test.get(), type, nullptr);
// Ici je visualise l'objet C++ en python
PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g, d);
PyRun_String("print(testdate.toString())", Py_file_input, g, d);
test->setDate(QDate{2000,02,03});
// Ici je visualise en python que l'objet a été modifié en c++
PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g, d);
Py_FinalizeEx();
```

Le mar. 27 août 2019 à 11:48, Phil Thompson <[hidden email]> a écrit :
Have you read this...

https://www.riverbankcomputing.com/static/Docs/sip/embedding.html

On 27/08/2019 09:45, Alexis Barbot wrote:
> What do you mean? Should I import this module in the python context? I
> tried adding this line wihtout any effect:
> `PyRun_SimpleString("import PyQt5.QtCore")`
>
> If we're speaking about some cpp header to include, I can't see which
> one
> it is.
> Thanks
>
> Le mar. 27 août 2019 à 10:25, Phil Thompson
> <[hidden email]> a
> écrit :
>
>> On 27/08/2019 08:29, Alexis Barbot wrote:
>> > Thanks for these replies,
>> >
>> > First of all, I had a look at PythonQt which indeed looked promising in
>> > my
>> > case. However I had toubles to build it, so I skipped that solution.
>> > Now I
>> > understand that this was probably caused by the compilation attempt
>> > with
>> > mingw while using a binary python installer, obviously compiled using
>> > msvc.
>> > Furthermore, I got some success with PyQt: after preparing all paths
>> > and
>> > adding several flags to the configure command, I could perform the
>> > complete
>> > build wihtout errors. I so tried to write a small piece of code to
>> > validate
>> > my usage. It builds correctly, but it suddenly stop while running
>> > without
>> > any error message. Here is the code:
>> >
>> > ```
>> > #include <QDebug>
>> > #include <Python.h>
>> > #include <QDateTime>
>> > #include <sipAPIQtCore.h>
>> > #include <memory>
>> >
>> > int main(int argc, char* argv[])
>> > {
>> >     qDebug() << "start";
>> >     Py_Initialize();
>> >     auto d = PyDict_New();
>> >     auto test = std::make_unique<QDateTime>();
>> >     auto pyTest = sipConvertFromType(test.get(), sipType_QDateTime,
>> > nullptr);
>> >     qDebug() << "end";
>> >     Py_FinalizeEx();
>> >     return 0;
>> > }
>> > ```
>> >
>> > It sounds like everything is installed but I'm missing some
>> > initialization
>> > step. Is that possible? Or maybe there's something else I should
>> > check/try?
>> > Many thanks for your help.
>>
>> You haven't imported PyQt5.QtCore.
>>
>> Phil
>>
>
> _______________________________________________
> PyQt mailing list    [hidden email]
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Phil Thompson-5
On 29/08/2019 17:21, Alexis Barbot wrote:

> I looked at it, but it seems I didn't catch the point (or possibly the
> moment I read it I did not figure out it could be what I needed...). I
> now
> understand that it explains I should get the c api dynamically to call
> it,
> whereas I was trying to call static method. I could get something
> roughtly
> working this way, with pyqt compiled in static (see code below). I'm
> currently trying to clean everythind, but I realized I had to upgrade
> Qt
> for that, as I can't find a PyQt package for Qt5.9 (sad, as it's a
> LTS). So
> I'll keep you updated on my progress.

See...

https://www.riverbankcomputing.com/static/Docs/PyQt5/installation.html#understanding-the-correct-version-to-install

> In my tests I realized something: is there some special care to do with
> containers while passing from C++/python? In my first attemp to pass a
> QVariantMap the items added after SetItem to python are not visible
> from
> python? (and items modified in python are not modified in c++). Any
> special
> thoughts about this?

Impossible to say without example code.

> Thanks for all your help
>
> Alexis
>
> ```
> Py_Initialize();
> PyEval_InitThreads();

The following code...

> auto sipModule = PyImport_ImportModule("sip");
> PyImport_ImportModule("PyQt5.sip");
> auto sipAPI = (const sipAPIDef*)PyCapsule_Import("sip._C_API", 0);
> PyCapsule_Import("PyQt5.QtCore._C_API", 0);
> auto sipModuleDict = PyModule_GetDict(sipModule);
> auto sip_sipmod = PyImport_ImportModule("PyQt5.sip");
> auto sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod),
> "_C_API");
>
> sipAPI_QtCore = reinterpret_cast<const
> sipAPIDef*>(PyCapsule_GetPointer(sip_capiobj, "PyQt5.sip._C_API"));
> qpycore_init();
> sipExportModule(&sipModuleAPI_QtCore, SIP_API_MAJOR_NR,
> SIP_API,MINOR_NR,
> 0);

...only needs to be...

sipAPI_QtCore = reinterpret_cast<const
sipAPIDef*>(PyCapsule_Import("PyQt5.sip._C_API", 0));
PyImport_ImportModule("PyQt5.QtCore")

...but I haven't actually tested it.

> auto m = PyImport_AddModule("__main__");
> auto g = PyModule_GetDict(m);
> auto d = PyDictNew();
>
> auto test = std::make_unique<QDateTIme>(QDateTIme::currentDateTime);
> auto type = sipAPI_QtCore->api_find_type("QDateTime);
> auto pyTest = sipAPI_QtCore->api_convert_from_type(test.get(), type,
> nullptr);
> // Ici je visualise l'objet C++ en python
> PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g,
> d);
> PyRun_String("print(testdate.toString())", Py_file_input, g, d);
> test->setDate(QDate{2000,02,03});
> // Ici je visualise en python que l'objet a été modifié en c++
> PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g,
> d);
> Py_FinalizeEx();
> ```

Make sure you aren't #including sipAPIQtCore.h. Those files are internal
and contain nothing public.

Phil

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Alexis Barbot
Thanks Phil,

I recompiled PyQt5.13 against Qt5.12 mingw32. I had to modify the qmake generated .pro to add "QMAKE_CXXFLAGE += "-D_hypot=hypot", and add "-lpython" to "LIBS" to every sub project, but it finally compiled. Now I'm trying to run an exemple as you said, but it crashes without explainations. Here is the code sample:

#include <sip.h>
#include <Python.h>
#include <QDateTime>

...

Py_Initialize();
PyImport_ImportModule("sip");
auto sipAPI_QtCore = reinterpret_cast<const sipAPIDef*>(PyCapsule_Import("PyQt5.sip._C_API", 0));
PyImport_ImportModule("PyQt5.QtCore");
auto type = sipAPI_QtCore->api_find_type("QDateTime");

Could someone confirm me this example should work, please?
Thanks

Alexis

Le jeu. 29 août 2019 à 18:48, Phil Thompson <[hidden email]> a écrit :
On 29/08/2019 17:21, Alexis Barbot wrote:
> I looked at it, but it seems I didn't catch the point (or possibly the
> moment I read it I did not figure out it could be what I needed...). I
> now
> understand that it explains I should get the c api dynamically to call
> it,
> whereas I was trying to call static method. I could get something
> roughtly
> working this way, with pyqt compiled in static (see code below). I'm
> currently trying to clean everythind, but I realized I had to upgrade
> Qt
> for that, as I can't find a PyQt package for Qt5.9 (sad, as it's a
> LTS). So
> I'll keep you updated on my progress.

See...

https://www.riverbankcomputing.com/static/Docs/PyQt5/installation.html#understanding-the-correct-version-to-install

> In my tests I realized something: is there some special care to do with
> containers while passing from C++/python? In my first attemp to pass a
> QVariantMap the items added after SetItem to python are not visible
> from
> python? (and items modified in python are not modified in c++). Any
> special
> thoughts about this?

Impossible to say without example code.

> Thanks for all your help
>
> Alexis
>
> ```
> Py_Initialize();
> PyEval_InitThreads();

The following code...

> auto sipModule = PyImport_ImportModule("sip");
> PyImport_ImportModule("PyQt5.sip");
> auto sipAPI = (const sipAPIDef*)PyCapsule_Import("sip._C_API", 0);
> PyCapsule_Import("PyQt5.QtCore._C_API", 0);
> auto sipModuleDict = PyModule_GetDict(sipModule);
> auto sip_sipmod = PyImport_ImportModule("PyQt5.sip");
> auto sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod),
> "_C_API");
>
> sipAPI_QtCore = reinterpret_cast<const
> sipAPIDef*>(PyCapsule_GetPointer(sip_capiobj, "PyQt5.sip._C_API"));
> qpycore_init();
> sipExportModule(&sipModuleAPI_QtCore, SIP_API_MAJOR_NR,
> SIP_API,MINOR_NR,
> 0);

...only needs to be...

sipAPI_QtCore = reinterpret_cast<const
sipAPIDef*>(PyCapsule_Import("PyQt5.sip._C_API", 0));
PyImport_ImportModule("PyQt5.QtCore")

...but I haven't actually tested it.

> auto m = PyImport_AddModule("__main__");
> auto g = PyModule_GetDict(m);
> auto d = PyDictNew();
>
> auto test = std::make_unique<QDateTIme>(QDateTIme::currentDateTime);
> auto type = sipAPI_QtCore->api_find_type("QDateTime);
> auto pyTest = sipAPI_QtCore->api_convert_from_type(test.get(), type,
> nullptr);
> // Ici je visualise l'objet C++ en python
> PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g,
> d);
> PyRun_String("print(testdate.toString())", Py_file_input, g, d);
> test->setDate(QDate{2000,02,03});
> // Ici je visualise en python que l'objet a été modifié en c++
> PyDict_SetItem(d, PyUnicode_FromString("testdate"), Py_file_input, g,
> d);
> Py_FinalizeEx();
> ```

Make sure you aren't #including sipAPIQtCore.h. Those files are internal
and contain nothing public.

Phil


_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: Advices on embedding python in Qt/C++ application

Phil Thompson-5
On 03/09/2019 17:23, Alexis Barbot wrote:

> Thanks Phil,
>
> I recompiled PyQt5.13 against Qt5.12 mingw32. I had to modify the qmake
> generated .pro to add "QMAKE_CXXFLAGE += "-D_hypot=hypot", and add
> "-lpython" to "LIBS" to every sub project, but it finally compiled. Now
> I'm
> trying to run an exemple as you said, but it crashes without
> explainations.
> Here is the code sample:
>
> #include <sip.h>
> #include <Python.h>
> #include <QDateTime>
>
> ...
>
> Py_Initialize();
> PyImport_ImportModule("sip");

You don't need this line ^^^^

> auto sipAPI_QtCore = reinterpret_cast<const
> sipAPIDef*>(PyCapsule_Import("PyQt5.sip._C_API", 0));
> PyImport_ImportModule("PyQt5.QtCore");
> auto type = sipAPI_QtCore->api_find_type("QDateTime");
>
> Could someone confirm me this example should work, please?

You should have error checking on each of the last 3 lines. If they are
working then debug it using whatever tools mingw provides.

Phil
_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt