我们可以使用 SWIG 为 Qt 应用程序制作 python 绑定吗?

Bru*_*Sun 3 c++ python qt swig

如何使用 SWIG 绑定到 QT 应用程序,我们的情况和这个帖子的情况差不多,里面说:

  • 我们有一个带有核心 Swig 绑定的大型 C++/Qt 应用程序。
  • 我们想在 python 中创建新的 UI 工具,这些工具需要使用我们的一些 C++ 小部件。所以我们需要绑定我们的 C++ 小部件。由于我们的核心绑定是用 Swig 编写的(我们对此很满意),我们需要使用相同的绑定工具绑定我们的小部件以实现兼容性。

似乎他们已经成功地在 SWIG 中创建了 Qt 的绑定,但是使用 swig 包装 QT 似乎并不容易,因为带有宏 Q_OBJECT 的 QT 应用程序将在预编译时生成 moc 文件,并在编译时使用这些文件。我试过这个:

>> swig -c++ -python application.i
application.h:46: Error: Syntax error in input(3)
Run Code Online (Sandbox Code Playgroud)

它总是给出关于指示 Q_OBJECT 的第 46 行的错误。

我还发现herehere说不可能使用swig来包装QT,我对此感到很困惑,如果不可行,有人可以对此有所了解,或者如果可以,请举一个关于使用SWIG wrap QT的简单示例. 提前致谢。

更新源文件:application.h

#ifndef   APPLICATION_H_
#define   APPLICATION_H_

#include <QApplication>

class frameApplication : public QApplication
{
    Q_OBJECT

public:
    frameApplication (){};
    virtual ~frameApplication();

private slots:
    void OnExitApp();

};
#endif  // APPLICATION_H_
Run Code Online (Sandbox Code Playgroud)

应用程序.i

%module application
%{
#include "application.h"
%}
%include "application.h"
Run Code Online (Sandbox Code Playgroud)

这是 application.h 的简化版本,使用上面的 SWIG 命令,错误信息除了行号之外保持不变。

Rei*_*ica 5

我们可以使用 SWIG 为 Qt 应用程序制作 python 绑定吗?

是的

发生错误是因为您的头文件使用了 SWIG 不知道的宏。当然,C++ 编译器也不知道它们。

SWIG 需要预处理您的输入。要做到这一点,它需要知道两者的包括路径的Qt,并在需要Qt的头工作的定义。

在我使用 Widgets 包的特定项目中,在 OSX Qt 安装中,SWIG 需要以下参数,例如:

-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB \
-I/Qt/5.6.0/lib/QtWidgets.framework/Headers \ 
-I/Qt/5.6.0/lib/QtGui.framework/Headers \ 
-I/Qt/5.6.0/lib/QtCore.framework/Headers \ 
-I/Qt/5.6.0/mkspecs/macx-clang
Run Code Online (Sandbox Code Playgroud)

SWIG 在很大程度上避免了丢失包含文件的问题。即使包含文件丢失,它也会尽力解析输入,并且即使它们未定义,也会对各种标识符的含义做出一些假设,但是当出现未知宏时,它无能为力扩展为单个标识符。

获得必要的定义 ( -D) 和包含路径 ( -I) 选项的最简单方法是构建您的代码并从编译器的命令行中获取这些选项。SWIG有目的地使用与大多数 C/C++ 编译器相同的选项语法 - 使传递数据更容易。

应该说 SWIG 对信号和槽没有什么特别的了解:它们只是 C++ 方法。SWIG 生成的任何绑定都不支持使用 Qt 5 的新connect语法来链接信号和插槽。您仍然可以使用 Qt 4 语法,将 C 字符串方法签名传递给connect,例如:

// with SIGNAL/SLOT macros
connect(obj1, SIGNAL(foo(QString)), obj2, SLOT(bar(QString)));
// without SIGNAL/SLOT macros - as you would call from a SWIG binding
connect(obj1, "2foo(QString)\0", obj2, "1bar(QString)\0");
Run Code Online (Sandbox Code Playgroud)

方法签名需要以额外的空终止符作为后缀。信号以 为前缀'2',槽以 为前缀'1',其他可调用方法以 为前缀'0'

除非您使用 private QMetaObjectBuilder,否则您将无法定义新信号或可调用方法;看到这里