13

I would like to embed Python interpreter 3.4 into a Qt 5.2.1 application (64-bit). However I'm having build issues, I mean when I include Python header in the main.cpp it compiles fine.

#include <python.h>
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  MainWindow w;
  w.show();

  return a.exec();
}

but when I put it anywhere else (after Qt headers)

//
// embedpytest.cpp
//
#include <QLibrary>
#include <python.h>


EmbedPyTest::EmbedPyTest()
{
}

I get compile errors:

C:\Python34\include\object.h:435: error: C2059: syntax error : ';'
C:\Python34\include\object.h:435: error: C2238: unexpected token(s) preceding ';'

enter image description here

It's very similar problem to this one, but the solution is not working

Embedding Python in Qt 5

Anyone knows how to solve this issue ? or suggest some clean workaround so that python.h and Qt5 can live together happily ever after ?

Community
  • 1
  • 1
krusty
  • 340
  • 3
  • 13

2 Answers2

28

Another way to avoid the conflict regarding 'slots', without the need for deactivating the keywords signals/slots/emit (which may be undesirable for large Qt projects), is to locally "park" the offending keyword while Python.h is included, and then reassign it. To achieve this, replace every occurrence of #include "Python.h" by the following block:

#pragma push_macro("slots")
#undef slots
#include "Python.h"
#pragma pop_macro("slots")

Or, more conveniently, put the above code in its own header, e.g. Python_wrapper.h, and replace all occurrences of #include "Python.h" by #include "Python_wrapper.h".

andreasdr
  • 3,804
  • 4
  • 28
  • 32
  • That's perfect, compiles with msvc & clang on macOS at least. Definitely the correct answer! – matthieu Dec 13 '18 at 16:58
  • It works on my ubuntu 20.04 Qt project, Better answer than the accepted one. – Vinay Kumar Feb 03 '21 at 16:59
  • This fixed the syntax error but now it's giving me `Undefined symbols _Py_DecodeLocale`. The application runs fine when I comment it out but it runs wrong version of python.. any ideas on how to fix this? – vlovero Apr 07 '21 at 18:18
10

The offending line is this:

PyType_Slot *slots; /* terminated by slot==0. */

The problem is that with this line, "slots" is a keyword by default in Qt. In order to use that variable name in other projects, you will need to use this in your project file:

CONFIG += no_keywords

For details, see the documentation:

Using Qt with 3rd Party Signals and Slots

It is possible to use Qt with a 3rd party signal/slot mechanism. You can even use both mechanisms in the same project. Just add the following line to your qmake project (.pro) file.

CONFIG += no_keywords

It tells Qt not to define the moc keywords signals, slots, and emit, because these names will be used by a 3rd party library, e.g. Boost. Then to continue using Qt signals and slots with the no_keywords flag, simply replace all uses of the Qt moc keywords in your sources with the corresponding Qt macros Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT.

Community
  • 1
  • 1
László Papp
  • 51,870
  • 39
  • 111
  • 135
  • makes sense but doesn't seem to work. I just tried CONFIG += no_keywords but it's a change for the worse I mean I get 114 errors. – krusty Apr 14 '14 at 20:21
  • true that works, but I have QObject's classes in my project and seems its causing problems. Add to the example some empty class with base class e.g. QOject http://paste.kde.org/p9qrwvve0 When I try to build I get 36 error. Any suggestion how to fix this ? – krusty Apr 14 '14 at 20:41
  • @krusty: that is _not_ an empty class. Change signals to Q_SIGNALS and slots to Q_SLOTS. See the last paragraph of the answer, i.e. the quoted documentation. – László Papp Apr 14 '14 at 20:42
  • 1
    thank you, now I get it. Sorry sometimes I need to 'digest' new stuff. – krusty Apr 14 '14 at 21:21
  • 1
    Thanks a lot for this answer, it helps immensely! As a side note, if you don't have a qmake project because you're using visual studio, you can just define `QT_NO_KEYWORDS` for the same effect. – DJMcMayhem Sep 13 '16 at 19:18
  • Is this the only way around this problem? I'm faced with embedding Python in a huge existing Qt/C++ application. With this solution, that's a lot of searching/replacing throughout the code, and a lot of people who have to change their habits. Is there any other way to resolve/avoid the 'slots' conflict? – andreasdr Mar 16 '18 at 23:46
  • I found a solution; I'll post it as a separate answer. – andreasdr Mar 19 '18 at 09:11