[原][osg][QT]osg与QT界面结合的简单例子二

时间:2021-01-17 20:50:05
//main.cpp

#include "VREObliqueEditorQTWindow.h"
#include <QtWidgets/QApplication>
#include <QTextCodec>
#include <QFileInfo>

int main(int argc, char *argv[])
{
    QTextCodec *xcodec = QTextCodec::codecForLocale();
    QString exeDir = xcodec->toUnicode(QByteArray(argv[0]));
    QString BKE_CURRENT_DIR = QFileInfo(exeDir).path();
    QStringList  libpath;
    libpath << BKE_CURRENT_DIR + QString::fromLocal8Bit("/plugins/platforms");
    libpath << BKE_CURRENT_DIR << BKE_CURRENT_DIR + QString::fromLocal8Bit("/plugins/imageformats");
    libpath << BKE_CURRENT_DIR + QString::fromLocal8Bit("/plugins");
    libpath << QApplication::libraryPaths();
    QApplication::setLibraryPaths(libpath);
    ////以上是跑qt的环境变量

    QApplication a(argc, argv);
    
    VREObliqueEditor* mw = new VREObliqueEditor();
    mw->init();
    mw->show();

    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
    return a.exec();
}

主函数仅仅是QT的调用

 

#pragma once
//VREObliqueEditorQTWindow.h

#include <QtWidgets/QMainWindow>
#include "ui_VREObliqueEditor.h"

class ViewerQT;
class VREObliqueEditor : public QMainWindow
{
    Q_OBJECT

public:
    VREObliqueEditor(QWidget *parent = Q_NULLPTR);
    void init();
private:
    Ui::VREObliqueEditorClass ui;

    ViewerQT * m_viewer;    

    void OSGInit();
};

QT主窗口头文件

 

//VREObliqueEditorQTWindow.cpp
#include "VREObliqueEditorQTWindow.h"

#include "VREOSGWidget.h"

VREObliqueEditor::VREObliqueEditor(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    m_viewer = new ViewerQT;
}

void VREObliqueEditor::init()
{
    OSGInit();
    showMaximized();
    setCentralWidget(m_viewer);
}


void VREObliqueEditor::OSGInit()
{

    osg::ref_ptr<osg::Node>  loadedModel = osgDB::readNodeFile("cow.osg");
    m_viewer->setCameraManipulator(new osgGA::TrackballManipulator);
    m_viewer->setSceneData(loadedModel.get());

    m_viewer->addEventHandler(new osgViewer::StatsHandler());
    m_viewer->addEventHandler(new osgViewer::WindowSizeHandler());

}

QT主窗口头文件

 

#pragma once
//VREOSGWidget.h

#include <osg/ArgumentParser>
#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>

#include <osgDB/ReadFile>
#include <QtCore/QString>
#include <QtCore/QTimer>
#include <QtGui/QKeyEvent>
#include <QtOpenGL/QGLWidget>
#include <iostream>


using Qt::WindowFlags;

class AdapterWidget :public QGLWidget
{
public:
    AdapterWidget(QWidget *parent = 0, const char* name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0);

    virtual ~AdapterWidget()
    {

    }

    osgViewer::GraphicsWindow* getGraphicsWindow()
    {
        return _gw.get();
    }

    const osgViewer::GraphicsWindow* getGraphicsWidow()const
    {
        return _gw.get();
    }
protected:
    virtual void resizeGL(int width, int height);
    virtual void keyPressEvent(QKeyEvent* event);
    virtual void keyReleaseEvent(QKeyEvent* event);
    virtual void mousePressEvent(QMouseEvent* event);
    virtual void mouseReleaseEvent(QMouseEvent* event);//
    virtual void mouseMoveEvent(QMouseEvent* event);

    osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;

};



class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
public:
    ViewerQT(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0) :AdapterWidget(parent, name, shareWidget, f)
    {
        getCamera()->setViewport(new osg::Viewport(0, 0, width(), height()));
        getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width()) / static_cast<double>(height()), 1.0f, 10000.0f);
        getCamera()->setGraphicsContext(getGraphicsWindow());

        setThreadingModel(osgViewer::Viewer::SingleThreaded);
        connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));//并且把它的timeout()连接到适当的槽。当这段时间过去了,它将会发射timeout()信号。

        _timer.start(10);//使用start()来开始

    }

    virtual void paintGL()
    {
        frame();
    }
protected:
    QTimer _timer;
};

osg窗口源文件

 

#include "VREOSGWidget.h"
//VREOSGWidget.cpp


AdapterWidget::AdapterWidget(QWidget *parent, const char* name, const QGLWidget * shareWidget, WindowFlags f) :QGLWidget(parent, shareWidget, f)
{
    _gw = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height());
    setFocusPolicy(Qt::ClickFocus);
}

void AdapterWidget::resizeGL(int width, int height)
{
    _gw->getEventQueue()->windowResize(0, 0, width, height);
    _gw->resized(0, 0, width, height);

}
void AdapterWidget::keyPressEvent(QKeyEvent* event)
{
    _gw->getEventQueue()->keyPress((osgGA::GUIEventAdapter::KeySymbol)*(event->text().toLatin1().data()));
}

void AdapterWidget::keyReleaseEvent(QKeyEvent* event)
{
    int keyAscii = (osgGA::GUIEventAdapter::KeySymbol)*(event->text().toLatin1().data());
    _gw->getEventQueue()->keyRelease(keyAscii);
    //if (keyAscii == 27)
    //    quit();
}


void AdapterWidget::mousePressEvent(QMouseEvent* event)
{
    int button = 0;
    switch (event->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()->mouseButtonPress(event->x(), event->y(), button);

}

void AdapterWidget::mouseReleaseEvent(QMouseEvent* event)
{
    int button = 0;
    switch (event->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);
}


void  AdapterWidget::mouseMoveEvent(QMouseEvent* event)
{
    _gw->getEventQueue()->mouseMotion(event->x(), event->y());

}

osg窗口源文件

 

一个简单osg与QT窗口的结合

需要开发QT窗口控件,就在"ui_VREObliqueEditor.h"上与“QT主窗口”做文章

需要开发OSG则正常开发