设为首页 收藏本站
查看: 820|回复: 0

[经验分享] 用c++和python写GUI程序(python嵌入方式)

[复制链接]

尚未签到

发表于 2015-4-20 08:38:23 | 显示全部楼层 |阅读模式
  用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程序。。

  那么我们需要做的工作是让这个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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58633-1-1.html 上篇帖子: python基础学习笔记(十三) 下篇帖子: python基础学习笔记(十二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表