python directx_directX嵌入pyside
現在能用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)
最后得到的handl就可以傳個c模塊去初始化d3d了。
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()
代碼中的CallBacks是自己用c++定義的模塊,給GUI調用用的。上面的代碼里用到了CallBacks.initD3D()和CallBacks.render()。什么,你不知道怎么寫C++模塊?去看開頭說的那篇文章先。。。
MainWindow這個類是自己定義的GUI框架類,里邊有一個窗口喚作renderWin,我們把它的handl傳給了CallBacks.initD3D()。
-----------------------------------------------------------------------
另:之前研究怎么做directx嵌入qt的時候翻到這篇文章。里面提到了DX嵌入Qt必須要做以下兩點:
1) OverrideQWidget::paintEngineto return NULL
2) CallQWidget::setAttribute(Qt::WA_PaintOnScreen, true)
我嘗試之后發現這兩點做不做都沒啥區別,我沒這些代碼dx依然在我的pyside里面跑的好好的。感覺既然我們都用dx把渲染窗口全部重畫了,那qt原本的繪制機制就不用再去管它了。不知道我的做法會不會有什么問題,忘大家指點。
另2:這里只講了qt方面的嵌入,實際上按我的經驗(我沒有實際嘗試),dx嵌入wxpython也是可以的。wx的窗體里有一個GetHandle()函數可以獲得handl。渲染調用只要放到OnIdle()事件中就行,記得調用下Idle event的requestMore()。
總結
以上是生活随笔為你收集整理的python directx_directX嵌入pyside的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: #今日论文推荐# 2名全色盲儿童部分恢复
- 下一篇: 番茄工作法总结-第四章:中断
