将OSG嵌入QT窗口系统中,实现拖拽界面

来源:互联网 发布:别墅设计软件下载 编辑:程序博客网 时间:2024/06/07 14:10

将OSG嵌入QT窗口系统中,实现拖拽界面


一、原理

OSG底层使用的是OpenGL图形系统,QT也增加了对OpenGL的支持,因此,可以通过QT的OpenGL模块,实现将OSG窗口嵌入到QT中,这样可以充分利用QT的UI界面设计,满足OSG的2D的界面系统的不足。当然除了使用OSG做2D渲染特效,可以尽情享受QT界面设计带来的方便。


二、准备

1. QT对OpenGL的支持:

QT中,场景视图模型模块,可以使用OpenGL绘制基本图元。视图,即:QGraphicsView ,场景,即:QGraphicsScene,当然还有基本图元项,QGraphicsItem,这里暂不介绍。
简单设计思路:我们新建一个QT MainWindow项目。首先,将场景,加入到视图中,接着,将视图加入MainWindow中,这样以后,我们就可以使用MainWindow在视图中浏览场景,场景包含OSG内容,这样,我们就达到了目的。

2. OSG窗口移植:

OSG的窗口API中,可以嵌入各种各样的窗口系统,这给我移植到QT带来的可能,在OSG参考文档中,我选择使用GraphicsWindowEmbedded 来创建可移植的窗口。

三、QT 模型视图框架

QT环境:

qt-opensource-windows-x86-msvc2010_opengl-5.4.1.exe
qt-vs-addin-1.2.4-opensource.exe

设计:



视图类QGraphicsView

GLView.h
GLView.cpp

文件:GLView.h
#pragma once#include <QtWidgets/QGraphicsView>#include <QtOpenGL/QGLWidget>#include <QtGui/QResizeEvent>#include "GLScene.h"class GLView : public QGraphicsView{public:GLView(QWidget *parent = 0);~GLView(void);protected://更新视图的时候,更新场景void resizeEvent(QResizeEvent *event);public:QGLWidget *m_widget;GLScene *m_scene;};

文件:GLView.cpp

#include "GLView.h"#include <QtWidgets/QMessageBox>GLView::GLView(QWidget *parent):QGraphicsView(parent),m_widget(new QGLWidget(QGLFormat(QGL::DoubleBuffer))),m_scene(new GLScene(this)){this->resize(800,600);//设置视口大小this->setViewport(m_widget);//将m_widget设置为视口:为了使用OpenGL渲染,你要设置一个新的QGLWidget作为QGraphicsView的视口m_widget->setMouseTracking(true);//鼠标追踪this->viewport()->setMinimumSize(1,1);this->setScene(m_scene);this->setMinimumSize(1,1); //设置视图的最小尺寸this->scene()->setSceneRect(0,0,this->width(),this->height());//设置场景大小this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);//设置视图的更新方式:整个视图更新}GLView::~GLView(void){}//更新视图的时候,更新场景void GLView::resizeEvent( QResizeEvent *event ){//更新场景大小m_scene->setSceneRect(this->rect().left(),this->rect().right(),this->rect().width(),this->rect().height());m_scene->resizeViewer();}

场景类QGraphicsScene

文件:GLScene.h

#pragma once#include <QtWidgets/QGraphicsScene>#include <QtWidgets/qgraphicsscene.h>#include <QtWidgets/QGraphicsSceneEvent>#include <QTimerEvent>#include <QtGui//QPainter>#include "OsgLib.h"#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osgGA/TrackballManipulator>#include <osgViewer/ViewerEventHandlers>#include "KeyBoardMap.h"static KeyBoardMap s_QtKeyboardMap;//按键映射class GLScene :public QGraphicsScene{public:GLScene(QObject *parent = 0);~GLScene(void);protected://绘制场景void drawBackground(QPainter *painter, const QRectF &rect);//窗口更新函数:使用定时器,定时更新void timerEvent(QTimerEvent *);protected://鼠标事件void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent);void wheelEvent(QGraphicsSceneWheelEvent * wheelEvent);//键盘按键void keyPressEvent(QKeyEvent * keyEvent);void keyReleaseEvent(QKeyEvent * keyEvent);int   timer_id;public://更新OSG窗口void resizeViewer();void setKeyboardModifiers( QInputEvent* event );//组合键public:osg::ref_ptr<osgViewer::Viewer> m_viewer;};

文件:GLScene.cpp

#include "GLScene.h"GLScene::GLScene(QObject *parent):QGraphicsScene(parent),m_viewer(NULL),timer_id(0){//OSG初始化m_viewer = new osgViewer::Viewer;m_viewer->setUpViewerAsEmbeddedInWindow(0,0,800,600);//设置窗口的嵌入大小m_viewer->setSceneData(osgDB::readNodeFile("glider.osg"));m_viewer->setCameraManipulator(new osgGA::TrackballManipulator);//添加操作器m_viewer->addEventHandler(new osgViewer::StatsHandler);//状态信息m_viewer->realize();//实例化GraphicsContexttimer_id = startTimer(0);//当定时器触发时,应用程序会发送一个QTimerEvent,如果参数为0,那么定时器事件每次发生时没有窗口系统事件处理。}GLScene::~GLScene(void){}//绘制场景void GLScene::drawBackground( QPainter *painter, const QRectF &rect ) {painter->beginNativePainting();painter->setRenderHint(QPainter::Antialiasing);//抗锯齿m_viewer->frame();//m_viewer->getViewerBase()->frame();painter->endNativePainting();}//窗口更新函数void GLScene::timerEvent(QTimerEvent *){this->update();}void GLScene::mousePressEvent( QGraphicsSceneMouseEvent * mouseEvent ){//std::cout<<"mousePressEvent"<<std::endl;QGraphicsScene::mousePressEvent(mouseEvent);int button = 0;switch ( mouseEvent->button() ){case Qt::LeftButton: button = 1; break;case Qt::MidButton: button = 2; break;case Qt::RightButton: button = 3; break;case Qt::NoButton: button = 0; break;default: button = 0; break;}//_gw->getEventQueue()->mouseButtonRelease( event->x(), event->y(), button );(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseButtonPress( mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button );}void GLScene::mouseReleaseEvent( QGraphicsSceneMouseEvent * mouseEvent ){//std::cout<<"mouseReleaseEvent"<<std::endl;QGraphicsScene::mouseReleaseEvent(mouseEvent);int button = 0;switch ( mouseEvent->button() ){case Qt::LeftButton: button = 1; break;case Qt::MidButton: button = 2; break;case Qt::RightButton: button = 3; break;case Qt::NoButton: button = 0; break;default: button = 0; break;}(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseButtonRelease( mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button );}void GLScene::mouseMoveEvent( QGraphicsSceneMouseEvent * mouseEvent ){//std::cout<<"mouseMoveEvent"<<std::endl;QGraphicsScene::mouseMoveEvent(mouseEvent);(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseMotion( mouseEvent->scenePos().x(), mouseEvent->scenePos().y());}void GLScene::mouseDoubleClickEvent( QGraphicsSceneMouseEvent * mouseEvent ){//std::cout<<"mouseDoubleClickEvent"<<std::endl;QGraphicsScene::mouseDoubleClickEvent(mouseEvent);int button = 0;switch ( mouseEvent->button() ){case Qt::LeftButton: button = 1; break;case Qt::MidButton: button = 2; break;case Qt::RightButton: button = 3; break;case Qt::NoButton: button = 0; break;default: button = 0; break;}(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseDoubleButtonPress( mouseEvent->scenePos().x(), mouseEvent->scenePos().y(), button );}void GLScene::wheelEvent( QGraphicsSceneWheelEvent * wheelEvent ){//std::cout<<"wheelEvent"<<std::endl;QGraphicsScene::wheelEvent(wheelEvent);(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->mouseScroll(wheelEvent->orientation() == Qt::Vertical ?(wheelEvent->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :(wheelEvent->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT) );}void GLScene::keyPressEvent( QKeyEvent * keyEvent ){setKeyboardModifiers(keyEvent);int value = s_QtKeyboardMap.remapKey( keyEvent );(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->keyPress( value );QGraphicsScene::keyPressEvent(keyEvent);}void GLScene::keyReleaseEvent( QKeyEvent * keyEvent ){//std::cout<<"keyReleaseEvent"<<std::endl;QGraphicsScene::keyReleaseEvent(keyEvent);int value = s_QtKeyboardMap.remapKey( keyEvent );(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->keyRelease( value );QGraphicsScene::keyPressEvent(keyEvent);}//OSG场景窗口更新void GLScene::resizeViewer(){//更新OSG窗口大小(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->resized(this->sceneRect().x(),this->sceneRect().y(),this->sceneRect().width(),this->sceneRect().height());(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->windowResize(this->sceneRect().x(),this->sceneRect().y(),this->sceneRect().width(),this->sceneRect().height());//?  更新状态S按键(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->requestRedraw();//?}//组合键void GLScene::setKeyboardModifiers( QInputEvent* event ){int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier);unsigned int mask = 0;if ( modkey & Qt::ShiftModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;if ( modkey & Qt::ControlModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL;if ( modkey & Qt::AltModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_ALT;(dynamic_cast<osgViewer::GraphicsWindow*> (m_viewer->getCamera()->getGraphicsContext()))->getEventQueue()->getCurrentEventState()->setModKeyMask( mask );}

QMainWindow类

文件:qtosgmainwindow.h

#ifndef QTOSGMAINWINDOW_H#define QTOSGMAINWINDOW_H#include <QtWidgets/QMainWindow>#include "ui_qtosgmainwindow.h"#include "GLView.h"class QtOsgMainWindow : public QMainWindow{Q_OBJECTpublic:QtOsgMainWindow(QWidget *parent = 0);~QtOsgMainWindow();protected://更新视图void resizeEvent(QResizeEvent *);private:Ui::QtOsgMainWindowClass ui;GLView *m_glview;};#endif // QTOSGMAINWINDOW_H

文件:qtosgmainwindow.cpp

#include "qtosgmainwindow.h"QtOsgMainWindow::QtOsgMainWindow(QWidget *parent): QMainWindow(parent){ui.setupUi(this);this->resize(800,600);//MainWindow设置窗口大小this->setCorner(Qt::BottomLeftCorner,Qt::LeftDockWidgetArea);this->setCorner(Qt::BottomRightCorner,Qt::RightDockWidgetArea);this->setCorner(Qt::TopLeftCorner,Qt::LeftDockWidgetArea);this->setCorner(Qt::TopRightCorner,Qt::RightDockWidgetArea);ui.gridLayout->setMargin(-1);m_glview = new GLView(this);//隐藏滚动条m_glview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);m_glview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);this->layout()->addWidget(m_glview);}QtOsgMainWindow::~QtOsgMainWindow(){}void QtOsgMainWindow::resizeEvent( QResizeEvent * ){std::cout<<"MainWindow resizeEvent."<<std::endl;m_glview->resize(this->rect().width(),this->rect().height());//更新视图}
注:文件使用KeyBoardMap.h等文件,注释掉即可,该文件用于QT按键与OSG按键的映射.

五、Main函数

#include "qtosgmainwindow.h"#include <QtWidgets/QApplication>int main(int argc, char *argv[]){QApplication a(argc, argv);QtOsgMainWindow w;w.show();return a.exec();}

到此,可实现QT窗口的,OSG显示.







0 0
原创粉丝点击