在Qt 5中嵌入Python3

13

我想将Python解释器3.4嵌入到一个Qt 5.2.1应用程序(64位)中。 然而,我在构建时遇到了问题。我的意思是,当我在main.cpp中包含Python头文件时,它可以编译成功。

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

但当我将它放在任何其他地方(Qt头文件后面)时

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


EmbedPyTest::EmbedPyTest()
{
}

我遇到编译错误:

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

在这里输入图片描述

这个问题与这个非常相似,但是解决方案并不起作用。

将Python嵌入Qt 5

有人知道如何解决这个问题吗?或者建议一些干净的解决方法,使python.h和Qt5能够快乐地生活在一起?


为什么那个答案对你不起作用? 因为它对我来说使用的是与你完全相同的 Python 和 Qt 版本。 - cmannett85
似乎不可能。我正在使用64位Python 3.4、64位Qt 5.2.1和Visual Studio 2012。 - krusty
我使用的是g++,也许这就是不同之处。 - cmannett85
2个回答

28
另一种避免“slots”冲突的方法是,不需要停用关键字信号/槽/发射(这可能对大型Qt项目不利),在包含Python.h时本地“停放”有问题的关键字,然后重新分配它。为了实现这一点,请将每个#include "Python.h"替换为以下代码块:
#pragma push_macro("slots")
#undef slots
#include "Python.h"
#pragma pop_macro("slots")

或者更方便地,将上述代码放在自己的头文件中,例如Python_wrapper.h,并将所有出现的#include "Python.h"替换为#include "Python_wrapper.h"

太完美了,在macOS上使用msvc和clang编译至少可以通过。绝对是正确的答案! - matthieu
它在我的Ubuntu 20.04 Qt项目上运行良好,比被接受的答案更好。 - Vinay Kumar
这个修复了语法错误,但现在它给我 Undefined symbols _Py_DecodeLocale。当我将其注释掉时,应用程序可以正常运行,但是它运行的是错误版本的Python.. 有什么想法如何解决这个问题吗? - vlovero

10

有问题的那一行是这个:

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

问题在于,在Qt中,“slots”默认是关键字。为了在其他项目中使用该变量名,您需要在项目文件中使用以下内容:

<config>
  <qt>
    <app>
      <!-- Add this line to your project file -->
      <extra-compiler-defines>QT_NO_KEYWORDS</extra-compiler-defines>
    </app>
  </qt>
</config>
CONFIG += no_keywords

详细信息请参见文档

使用 Qt 与第三方信号/槽机制是可行的。您甚至可以在同一个项目中同时使用两种机制。只需将以下行添加到 qmake 项目(.pro)文件中即可。

CONFIG += no_keywords
它告诉Qt不要定义moc关键字signals、slots和emit,因为这些名称将被第三方库(例如Boost)使用。然后,如果想继续在no_keywords标志下使用Qt信号和槽,只需用相应的Qt宏Q_SIGNALS(或Q_SIGNAL)、Q_SLOTS(或Q_SLOT)和Q_EMIT替换源代码中所有Qt moc关键字的使用。

听起来有道理,但似乎不起作用。我刚试过 CONFIG += no_keywords 但是变得更糟了,我的意思是我得到了114个错误。 - krusty
真的可以工作,但是我的项目中有QObject的类,似乎会引起问题。 在示例中添加一些空类,基类为QOject http://paste.kde.org/p9qrwvve0当我尝试构建时,出现了36个错误。有什么建议如何修复这个问题吗? - krusty
@krusty:那不是一个空类。将signals更改为Q_SIGNALS,将slots更改为Q_SLOTS。请参见答案的最后一段,即引用的文档。 - László Papp
1
谢谢,现在我明白了。有时候我需要“消化”新的东西,很抱歉。 - krusty
1
非常感谢这个答案,它帮了我很多!另外一点要注意的是,如果您没有qmake项目,因为您正在使用Visual Studio,则可以只需定义QT_NO_KEYWORDS来达到相同的效果。 - DJMcMayhem
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接