osgQt::GLWidget的坑
坑一:
最近做項目,需要在三個Qt的QWidget窗體上加載三維模型,但每次只顯示某一個QWidget窗體的三維模型場景,其它的兩個不顯示。于是想到用QStackedWidget將這三個Qt的QWidget窗體通過addWidget加載,這樣每次切換顯示時利用QStackedWidget類的setCurrentIndex或setCurrentWidget就行,代碼如下:
QMainWidget::QMainWidget(QWidget *parent): QStackedWidget(parent) {ui.setupUi(this);m_pManholeCoverWnd = new CManholeCoverWnd(this);m_pJzWnd = new CJzWnd(this);m_pLaunchWnd = new CLaunchWnd(this);addWidget(m_pManholeCoverWnd);addWidget(m_pJzWnd);addWidget(m_pLaunchWnd); }其中?QMainWidget是QStackedWidget子類,m_pManholeCoverWnd、m_pJzWnd、m_pLaunchWnd 都是QWidget派生的子類且都通過addWidget函數放入到QMainWidget中了,且在它們的構造函數內部都創建了一個osgQt::GLWidget對象,如下:
void CManholeCoverWnd::initOsg() {// 步驟一:初始化qt窗口系統osgQt::initQtWindowingSystem();// 步驟二:創建視口m_pViewer = new osgViewer::Viewer;// 步驟三:視口設為單線程(Qt5必須)m_pViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);// 步驟四:對視圖的操作,必須,否則無法顯示黑屏m_pViewer->setCameraManipulator(new osgGA::TrackballManipulator);// 步驟五:視口操作// 步驟六:設置osgQt視口(一個應用程序用opgQt同一時刻只能設置一個視口)osgQt::setViewer(m_pViewer.get());// 步驟七:創建窗口(2個都要,只創建osgQt::GLWidget會掛掉)m_pGLWidget = new osgQt::GLWidget(this);m_pGraphicsWindowQt = new osgQt::GraphicsWindowQt(m_pGLWidget);// 步驟八:設置視口m_pViewport = new osg::Viewport(0, 0, m_pGLWidget->width(), m_pGLWidget->height());//m_pViewport = new osg::Viewport();// 步驟九:設置攝像機視口范圍,未設置不會顯示,即窗口一片黑(刷新窗口但沒有內容顯示)m_pViewer->getCamera()->setViewport(m_pViewport);m_pViewer->getCamera()->setClearColor(osg::Vec4f(0.0235, 0.45, 0.67, 1.0));// 步驟十:設置刷新顯示內容,未設置不會顯示,即一片白(不會刷新窗口)m_pViewer->getCamera()->setGraphicsContext(m_pGraphicsWindowQt);m_spRoot = new osg::Group();// 步驟十一:顯示m_pGLWidget->show(); }?m_pGLWidget 就是?osgQt::GLWidget對象。CJzWnd、?CLaunchWnd類也有initOsg()函數,也在構造函數中調用了initOsg()函數,構造了一個?osgQt::GLWidget對象,但此時整個程序運行起來后,鍵盤、鼠標都不能用,程序假死。原因至今不知道。
坑二:
因為高度懷疑坑一的原因是同一個程序中不能同時加載多個osgQt::GLWidget對象,于是每次在坑一中的QMainWidget中接收到外部顯示三維模型場景指令時,通過QStackedWidget的removeWidget函數將上次加載的顯示三維場景的窗體部件移除,然后再通過insertWidget插入最新的顯示三維模型場景的窗體部件,代碼如下:
void QMainWidget::cmdSlot(const QString&qsMemo, EmOutMsgCmdType eCmd) {QWidget *pWnd = widget(1); // 取得上次的顯示三維場景的窗體部件removeWidget(pWnd); // 移除上次的顯示三維場景的窗體部件delete pWnd;pWnd = new CManholeCoverWnd(); insertWidget(1, pWnd); // 插入最新的三維場景的窗體部件setCurrentWidget(pWnd); // 顯示插入最新的三維場景的窗體部件 }這樣處理坑一假死的現象確實沒了,但有時在接收到指令切換顯示時又會假死(和坑一不同,坑一是程序起來就假死,這是接收指令切換窗體有時會假死,程序起來時不假死)。
原因至今不知道。
坑三:
為了避免坑一、坑二的假死問題,將坑一中的m_pManholeCoverWnd、? ? m_pJzWnd、?m_pLaunchWnd 這三個窗體合并到一個QWidget類中,即將CManholeCoverWnd、? ? CJzWnd、?CLaunchWnd 這三個類合并為一個類A(這樣代碼很亂,但沒辦法),在A類的構造函數中調用上述initOsg()構造osgQt::GLWidget對象,這樣只保證osgQt::GLWidget對象只有一個,假死問題解決。
但是在A類中構造的其它窗體或子窗體都無法顯示,即使是設置這些窗體為置頂也無法顯示,必須按win鍵(Ctl和Alt之間的那個鍵,有的電腦是Fn和Alt之間的鍵)才能顯示,后來發現原因是:osgQt::GLWidget對象必須在A類中構造的其它窗體或子窗體顯示出來后再顯示,也就是說osgQt::GLWidget對象必須后顯示才行,如果比A類中構造的其它窗體或子窗體先顯示,則這些A類中構造的窗體都無法顯示,原因至今不知道。
?
?
總結
以上是生活随笔為你收集整理的osgQt::GLWidget的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++编程实现多显示器控制(复制、横屏
- 下一篇: 爆炸般的伤害 dnf神圣符咒属性详细解析