【问题标题】:Embedding Python3 in Qt 5在 Qt 5 中嵌入 Python3
【发布时间】:2020-12-11 23:15:26
【问题描述】:

我想将 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 ';'

这个问题和这个问题很相似,但是解决方法不行

Embedding Python in Qt 5

有人知道如何解决这个问题吗?或建议一些干净的解决方法,以便 python.h 和 Qt5 以后还能幸福的生活在一起吗?

【问题讨论】:

  • 这个答案怎么不适合你?因为它使用与您完全相同的 Python 和 Qt 版本对我有用。
  • 似乎不可能。我正在使用 64 位 python 3.4、64 位 Qt 5.2.1 和 Visual Studio 2012
  • 我用的是g++,也许这就是区别。

标签: python c++ qt qmake qt-signals


【解决方案1】:

另一种避免“插槽”冲突的方法是to locally "park" the offending keyword while Python.h is included, and then reassign it,无需停用关键字信号/插槽/发射(这对于大型 Qt 项目可能不受欢迎)。为此,请将每次出现的#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 编译。绝对是正确答案!
  • 它适用于我的 ubuntu 20.04 Qt 项目,比接受的更好。
  • 这修复了语法错误,但现在它给了我Undefined symbols _Py_DecodeLocale。当我将其注释掉时,应用程序运行良好,但它运行错误版本的 python.. 有关如何解决此问题的任何想法?
【解决方案2】:

有问题的行是这样的:

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

问题在于,在这一行中,“slots”在 Qt 中是默认的关键字。为了在其他项目中使用该变量名,您需要在项目文件中使用它:

CONFIG += no_keywords

详情见documentation

将 Qt 与第 3 方信号和插槽一起使用

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

CONFIG += no_keywords

它告诉 Qt 不要定义 moc 关键字信号、插槽和发射,因为这些名称将被 3rd 方库使用,例如促进。然后继续使用带有 no_keywords 标志的 Qt 信号和槽,只需将源代码中所有 Qt moc 关键字的使用替换为相应的 Qt 宏 Q_SIGNALS(或 Q_SIGNAL)、Q_SLOTS(或 Q_SLOT)和 Q_EMIT。

【讨论】:

  • 有道理,但似乎不起作用。我刚刚尝试了 CONFIG += no_keywords 但它的变化变得更糟,我的意思是我得到了 114 个错误。
  • 确实可行,但我的项目中有 QObject 的类,似乎它会导致问题。在示例中添加一些带有基类的空类,例如QOject paste.kde.org/p9qrwvve0 当我尝试构建时出现 36 错误。有什么建议可以解决这个问题吗?
  • @krusty:这不是一个空类。将信号更改为 Q_SIGNALS,将插槽更改为 Q_SLOTS。请参阅答案的最后一段,即引用的文档。
  • 谢谢,我明白了。抱歉,有时我需要“消化”新东西。
  • 非常感谢这个答案,它有很大帮助!附带说明一下,如果您因为使用 Visual Studio 而没有 qmake 项目,则只需定义 QT_NO_KEYWORDS 即可获得相同的效果。
猜你喜欢
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多