directX嵌入pyside
时间:2011-04-07
来源:互联网
转:Shiren.Y
之前讲了如何用c++和python写GUI程序。
现在能用python来写GUI了,做为一个游戏程序员马上联想到的就是能不能用python来写游戏编辑器。
于是就尝试着把directx嵌入到pyside里面。
在一翻折腾下,directX和pyside,两个初看起来没什么关系的库,居然很好的结合起来。以后写编辑器又多了一个强力工具
下面说下整合directx+pyside比较关键的地方。
1.如何获取窗口句柄。
关键之中的关键就是如何那到用于初始化d3d的那一个窗口handl。这个在pyside里边几乎跟Qt下一样,调用窗口类的winId()函数,如果你用的PyQt那么直接将winId返回的值传给C的函数就好。而pyside要蛋疼一点,winId这函数居然返回的是一个PyCObject(注意不是PyObject),我们需要手动的转换一下。以下是转换的python代码:
复制代码
最后得到的handl就可以传个c模块去初始化d3d了。
2.如何刷新。
Qt没有类似wxWidget的OnIdle()事件,也不能像MFC里那样暴力的直接把渲染往消息循环里塞。
我们只好定义一个QTimer对象,每隔20,30毫秒就调用一次渲染函数。
搞定了以上两点,你的directX和pyside就能顺畅地合作了。下面贴一个没头没尾的关键片段。
复制代码
代码中的CallBacks是自己用c++定义的模块,给GUI调用用的。上面的代码里用到了CallBacks.initD3D()和CallBacks.render()。什么,你不知道怎么写C++模块?去看开头说的那篇文章先。。。
MainWindow这个类是自己定义的GUI框架类,里边有一个窗口唤作renderWin,我们把它的handl传给了CallBacks.initD3D()。
-----------------------------------------------------------------------
另:之前研究怎么做directx嵌入qt的时候翻到这篇文章。里面提到了DX嵌入Qt必须要做以下两点:
1) Override QWidget::paintEngine to return NULL
2) Call QWidget::setAttribute(Qt::WA_PaintOnScreen, true)
我尝试之后发现这两点做不做都没啥区别,我没这些代码dx依然在我的pyside里面跑的好好的。感觉既然我们都用dx把渲染窗口全部重画了,那qt原本的绘制机制就不用再去管它了。不知道我的做法会不会有什么问题,忘大家指点。
另2:这里只讲了qt方面的嵌入,实际上按我的经验(我没有实际尝试),dx嵌入wxpython也是可以的。wx的窗体里有一个GetHandle()函数可以获得handl。渲染调用只要放到OnIdle()事件中就行,记得调用下Idle event的requestMore()。
directX嵌入pyside
之前讲了如何用c++和python写GUI程序。
现在能用python来写GUI了,做为一个游戏程序员马上联想到的就是能不能用python来写游戏编辑器。
于是就尝试着把directx嵌入到pyside里面。
在一翻折腾下,directX和pyside,两个初看起来没什么关系的库,居然很好的结合起来。以后写编辑器又多了一个强力工具

下面说下整合directx+pyside比较关键的地方。
1.如何获取窗口句柄。
关键之中的关键就是如何那到用于初始化d3d的那一个窗口handl。这个在pyside里边几乎跟Qt下一样,调用窗口类的winId()函数,如果你用的PyQt那么直接将winId返回的值传给C的函数就好。而pyside要蛋疼一点,winId这函数居然返回的是一个PyCObject(注意不是PyObject),我们需要手动的转换一下。以下是转换的python代码:
- from ctypes import pythonapi, c_void_p, py_object
-
- pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
-
- pythonapi.PyCObject_AsVoidPtr.argtypes = [ py_object ]
-
- handl = pythonapi.PyCObject_AsVoidPtr(pycobj)
2.如何刷新。
Qt没有类似wxWidget的OnIdle()事件,也不能像MFC里那样暴力的直接把渲染往消息循环里塞。
我们只好定义一个QTimer对象,每隔20,30毫秒就调用一次渲染函数。
搞定了以上两点,你的directX和pyside就能顺畅地合作了。下面贴一个没头没尾的关键片段。
- # Self defined c++ modudle
-
- import CallBacks
-
-
-
-
-
- def render():
-
- CallBacks.render(0.02)
-
-
-
-
-
- # Module for convert PyCObject ot PyObject
-
- def PycobjToVoidPoint(pycobj):
-
- from ctypes import pythonapi, c_void_p, py_object
-
- pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
-
- pythonapi.PyCObject_AsVoidPtr.argtypes = [ py_object ]
-
- return pythonapi.PyCObject_AsVoidPtr(pycobj)
-
-
-
-
-
- def RunApp():
-
- app = QApplication((''))
-
- mainWin = MainWindow()
-
-
-
- timer = QTimer()
-
- timer.timeout.connect(render)
-
- timer.start(20)
-
-
-
- if(not CallBacks.initD3D( PycobjToVoidPoint(mainWin.renderWin.winId()) ) ):
-
- print 'initD3D false'
-
- return;
-
-
-
- mainWin.show()
-
- sys.exit(app.exec_())
-
-
-
-
-
- if __name__ == '__main__':
-
- RunApp()
MainWindow这个类是自己定义的GUI框架类,里边有一个窗口唤作renderWin,我们把它的handl传给了CallBacks.initD3D()。
-----------------------------------------------------------------------
另:之前研究怎么做directx嵌入qt的时候翻到这篇文章。里面提到了DX嵌入Qt必须要做以下两点:
1) Override QWidget::paintEngine to return NULL
2) Call QWidget::setAttribute(Qt::WA_PaintOnScreen, true)
我尝试之后发现这两点做不做都没啥区别,我没这些代码dx依然在我的pyside里面跑的好好的。感觉既然我们都用dx把渲染窗口全部重画了,那qt原本的绘制机制就不用再去管它了。不知道我的做法会不会有什么问题,忘大家指点。
另2:这里只讲了qt方面的嵌入,实际上按我的经验(我没有实际尝试),dx嵌入wxpython也是可以的。wx的窗体里有一个GetHandle()函数可以获得handl。渲染调用只要放到OnIdle()事件中就行,记得调用下Idle event的requestMore()。
作者: 中关村村草 发布时间: 2011-04-07
楼主好强,这个要学习!
作者: corefix 发布时间: 2011-04-07
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28