[PyQt] Advices on embedding python in Qt/C++ application
Phil Thompson
phil at riverbankcomputing.com
Thu Aug 29 17:48:44 BST 2019
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
More information about the PyQt
mailing list