用c++和python写GUI程序(python嵌入方式)
用python写GUI相比C++好处多多:语法简洁灵活,不用编译,自动垃圾回收,等等。很让我这个c++程序员眼红,自然要好好研究一下。如果用纯python的方式很简单,qt或者wxwidget这个两个GUI库的python版本都已经很成熟,直接拿来用就行了。但在一些核心逻辑是由c来完成的项目里,就需要结合c和python来做GUI程序。c+python做GUI程序是有点麻烦的。通常采用的是extending方式,也就是用c++写python的扩展模块,提供一系列接口来供python调用。但是这样的方式有一些缺点,一是c模块的编译比较麻烦,二是如果已有的c++代码不是很规范,要归纳出一套易用的接口是不太容易的。
所以就希望用python嵌入(embedding)c的方式:主程序还是c程序,将python写的界面嵌入到c程序中,在事件触发时python方面只要调用一下相应的c++函数就可以完成逻辑的处理。省去了编译python模块的麻烦。而且主程序是c写的,编译出二进制的可执行程序比直接给一个python脚本去执行给用户的体验也要好一点。。。研究了几天(本人是python新手)总算是总结出一套用Cpp + python写GUI界面的方法。
本文假定你已经能够熟练使用c/c++语言。并且至少能用python写一些简单的GUI程序。如果你希望编译运行本文给出的列子,你的环境需要配置好python,pyside,boost.python(这玩意的编译很烦人囧)
这里使用boost.python来实现python的嵌入。其实用python的C API也不是不可以,但是在导出python模块的时候boost要方便许多,可以少打很多字。。并且boost.python也极大的简化了python的嵌入,不用再去关心python的C API里面恼人的索引计数和难看的错误处理(使用异常机制)。
ok,罗嗦了一大堆,下面正式开始。首先,我们需要用python来写一个GUI界面,这是我的代码:
MainFrame.py:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
if(__name__ == '__main__'):
app = QApplication(sys.argv)
hellobt = QPushButton('Say Hello');
hellobt.show()
sys.exit(app.exec_())
这里用的是pyside。当然用什么gui库无所谓wxpython,pyqt都可以,这里只要完成一个最基础的只有一个按钮的UI就好。至于怎么写GUI这个不是我们的讨论范围。
如果你的机器上已经安装好了pyside环境的话,用python解释器运行这个文件,你会可见这样一个很搓的GUI程序。。
http://pic002.iyunv.com/images/2011/140028/2011040514262436.jpg
那么我们需要做的工作是让这个python写的界面在我们的C++代码里面跑起来。下面就是我们的main函数所在的main.cpp:
#include
int main()
{
using namespace boost::python;
// 初始化python环境
Py_Initialize();
try
{
// 导入main模块并获得main下的命名空间
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
// 在main的命名空间中运行我们的python界面
exec_file("MainFrame.py", main_namespace);
}
catch(...)
{
PyErr_Print();
}
return 0;
}
用你的编译器搞出一个可执行程序来,把我们一开始的MainFrame.py弄到程序的工作目录下,运行,我们就又看到了那个很搓的只有一个按钮的GUI。main.cpp的代码很简单,通过注释你应该能知道它干了些什么。要是对具体接口的使用还有疑问推荐你去翻翻boost.python的教材和手册。
好了,现在我们确实是把python嵌入进来了。但是我们的python和c++还是无法互相通信和调用。所以c++需要提供一些函数供python去调用。下面我们就来在main.cpp里声明一些c++提供给python的接口和模块。
#include
#include
using namespace boost::python;
void hello()
{
std::cout
页:
[1]