![]() |
VR-Forces 4.0.4 Class Documentation
|
This example shows how to create a your own QT application with a Main Window that has a VR-Vantage view embedded into it.
It also adds a dockable widget with a second embedded view (and its own independent observer). Finally, it adds some standard VR-Vantage GUI elements, including a File Menu, File Toolbar, and a dockable panel that can display the OSG scene graph.
Create and show the main application:
QApplication app(argc, argv); ExampleEmbeddedMainWindow mainWindow; mainWindow.showMaximized();
Run the application:
return app.exec();
The example application has a GUI derived from QMainWindow. This is a very common way of building QT applications.
class ExampleEmbeddedMainWindow : public QMainWindow
The main window class owns some key VR-Vantage objects. It owns a DtDe (display engine) which is the core component for adding visualization to any application. It also owns a DtPluginManager which is responsible for loading all the VR-Vantage plug-ins.
The OpenGL graphics context needs to be owned and managed by the QT main window. We connect it the VR-Vantage display engine (and consequently OSG) via the DtOsgAdapterQtWidget. We use a second DtOsgAdapterWidget to embed the display engine into the dock widget.
The main window also owns a DtPage to display the scene graph tree;
as well as some QT widgets for menus and toolbars.
QMenu* myFileMenu; QToolBar* myFileToolBar; QAction* myOpenAction; QAction* myCloseAction; QAction* myExitAction;
The real work begins in the constructor of the main window.
ExampleEmbeddedMainWindow::ExampleEmbeddedMainWindow() : QMainWindow() , myPluginManager(0) , myDe(0) , myMainOSGWidget(0) , myMiniOsgWidget(0) { createDisplayEngine(); buildGui(); preDisplayEngineInitialize(); initializeDisplayEngine(); postDisplayEngineInitialize(); }
First, set up the display engine configuration and initializer.
void ExampleEmbeddedMainWindow::createDisplayEngine() { DtDeConfiguration deConfig; DtDeInitializer init; std::string displayName = DtDisplayConfiguration::DefaultDisplayString; displayName += " 1"; // Configure DtDeInitializer init.setDeMode(DtDeInitializer::MasterMode); init.setDisplayEngineName(displayName);
Create observer configurations for the main window and docked window and include them in the input driver configuration, and add the input driver configuration to the display engine initializer.
makVrv::DtObserverConfiguration observerConfig("Observer 1"); makVrv::DtObserverConfiguration observerConfig2("Observer 2"); makVrv::DtInputDriverConfiguration inputConfig; inputConfig.observerConfigurations().add(observerConfig); inputConfig.observerConfigurations().add(observerConfig2); inputConfig.setOptionalParameter( "windowDependent", "true" ); init.setInputDriverConfiguration( inputConfig );
Create a window configuration for each window, specifying the observer for each.
std::string wName = makVrv::DtWindowConfiguration::DefaultWindowString; wName += " 1"; DtWindowConfiguration wc(wName); std::string cName = makVrv::DtChannelConfiguration::DefaultChannelString; cName += " 1"; DtChannelConfiguration cc(cName); cc.setObserverName( "Observer 1" ); DtDisplayConfiguration dec(displayName); wc.setWindowType(DtWindowConfiguration::EmbeddedWindow); wc.channelConfigurations().add(cc); std::string wName2 = makVrv::DtWindowConfiguration::DefaultWindowString; wName2 += " 2"; DtWindowConfiguration wc2(wName2); std::string cName2 = makVrv::DtChannelConfiguration::DefaultChannelString; cName2 += " 2"; DtChannelConfiguration cc2(cName2); cc2.setObserverName( "Observer 2" ); wc2.setWindowType(DtWindowConfiguration::EmbeddedWindow); wc2.channelConfigurations().add(cc2); dec.windowConfigurations().add(wc); dec.windowConfigurations().add(wc2); deConfig.displayConfigurations().add(dec);
Create, intialize, and provide the display configuration to the display engine.
myDe = new DtDe(); myDe->setDeInitializer(init); myDe->setDeConfiguration(deConfig);
Finally, create a plug-in manager, and then initialize and load the plug-ins.
myPluginManager = new DtPluginManager(*myDe); #ifndef _WIN32 // DI-Guy links in Qt 3, which is incompatible with Qt 4 based applications. // The following code will exclude the DI-Guy plugin for Linux: std::list<std::string> excludePlugins; excludePlugins.push_back("../plugins/release/libvrvDiGuyPlugin.so"); myPluginManager->setExcludedPluginFiles(excludePlugins); #endif myPluginManager->initializePlugins(); }
Now we create the GUI. The interesting thing here is the DtQtIgTickerProvider. This provides us with a "ticker" that ticks the display engine as fast as the QT GUI will go. The rest of the function just sets up menus, toolbars, and the other things that would be part of this application.
void ExampleEmbeddedMainWindow::buildGui() { // Create an IG ticker to tick during Qt's idle time. DtQtDeTickerProvider& tickerProvider = DtQtDeTickerProvider::instance(*myDe); tickerProvider.ticker(this); // this needs an active Display to be hooked up properly DtSceneGraphTreeWidgetCreator* twc = new DtSceneGraphTreeWidgetCreator(*myDe); mySceneGraphTreeWidget = twc->create(this); QDockWidget* dock = new QDockWidget(tr("Scene Tree"), this); dock->setWidget(mySceneGraphTreeWidget); addDockWidget(Qt::LeftDockWidgetArea,dock,Qt::Vertical); setWindowTitle(tr("Embedded Example")); setWindowIcon(QIcon(":/images/Mak-de.png")); createActions(); createMenus(); createToolBars(); createStatusBar(); }
During the call to preDisplayEngineInitialize(), we override the functionality set up by plug-ins. We want to create a DtEmbeddedOsgWindow that uses a DtOsgAdapterQtWidget for its graphic context and we do that by installing a new creator with the DtWindowFactory.
// Set the display window creator function to use the Adapter widget. DtWindowFactory::instance(*myDe).setCreator( DtWindowConfiguration::EmbeddedWindow, new ExampleEmbeddedMainWindowViewCreator(this));
We have to tell our application framework not to try and create a QApplication, which already exists. We also have to tell it not to create a main window, since that already exists too.
// Register the qApp with the DtQApplicationProvider. DtQApplicationProvider::instance(*myDe).setQAppInstance(qApp); // Register null with the DtDeMainWindowProvider so that no main window // is ever created. This DtDe instance is embedded in a QMainWindow already. DtDeMainWindowProvider::registerInstance(*myDe, NULL);
Finally, everything is all set up and we can initialize the display engine:
void ExampleEmbeddedMainWindow::initializeDisplayEngine() { myDe->initialize(); }
VR-Vantage includes pre-built versions of the example application. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.
This example is an application. You can run it by running ./bin/exampleEmbedded.exe (on Windows) or ./bin/exampleEmbedded (on Linux). For more information about running examples, please see Running Applications and Examples.
/****************************************************************************** ** Copyright (c) 2008 MAK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: exampleEmbeddedMainWindow.h,v $ $Revision: 1.4 $ $State: Exp $ ******************************************************************************/ #ifndef exampleEmbeddedMainWindow_H #define exampleEmbeddedMainWindow_H // Include this header before any Qt header. #include <vrvUtil/signalslib.h> #include <vrvCore/DtDe.h> #include <vrvCore/DtVrvApplication.h> #include <vrvCore/DtPluginManager.h> #include <vrvOsgQt/DtOsgAdapterQtWidget.h> #include <vrvOsgQt/DtSceneGraphTreeWidget.h> #include <vrvCore/DtWindow.h> #include <vrvUtil/DtWindowConfiguration.h> #include <QtGui/QMainWindow> #include <osg/Group> #include <osg/Node> class QAction; class QMenu; class QTreeWidget; class QTreeWidgetItem; class ExampleEmbeddedMainWindow : public QMainWindow { Q_OBJECT public: ExampleEmbeddedMainWindow(); virtual ~ExampleEmbeddedMainWindow(); // The adapter widgets. These will become owned and // deleted by MainWindow. makVrv::DtOsgAdapterQtWidget* myMainOSGWidget; makVrv::DtOsgAdapterQtWidget* myMiniOsgWidget; void buildGui(); public slots: void open(); void closeFile(); protected: void preDisplayEngineInitialize(); void createDisplayEngine(); void overrideDisplayEngineFunctionality(); void initializeDisplayEngine(); void postDisplayEngineInitialize(); virtual void closeEvent(QCloseEvent *event); void createActions(); void createMenus(); void createToolBars(); void createStatusBar(); protected: makVrv::DtDe* myDe; makVrv::DtPluginManager* myPluginManager; makVrv::DtPage* mySceneGraphTreeWidget; QMenu* myFileMenu; QToolBar* myFileToolBar; QAction* myOpenAction; QAction* myCloseAction; QAction* myExitAction; }; class ExampleEmbeddedMainWindowViewCreator : public makVrv::DtWindowCreator { public: ExampleEmbeddedMainWindowViewCreator(ExampleEmbeddedMainWindow* window) { myWindow = window; } virtual makVrv::DtWindow* create(makVrv::DtDe&, makVrv::DtWindowConfiguration&); protected: ExampleEmbeddedMainWindow* myWindow; }; #endif
/****************************************************************************** ** Copyright (c) 2008 MAK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: exampleEmbeddedMain.cxx,v $ $Revision: 1.3 $ $State: Exp $ ******************************************************************************/ // Include this header before any Qt header. #include <vrvUtil/signalslib.h> #include <QtGui/QApplication> #include "exampleEmbeddedMainWindow.h" int main(int argc, char *argv[]) { // // This example illustrates how to embed a DtOsgView into a preexisting // application. // QApplication app(argc, argv); ExampleEmbeddedMainWindow mainWindow; mainWindow.showMaximized(); // // Notice how the preexisting applications event loop wasn't changed. // return app.exec(); }
/****************************************************************************** ** Copyright (c) 2008 MAK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: exampleEmbeddedMainWindow.cxx,v $ $Revision: 1.13 $ $State: Exp $ ******************************************************************************/ // Include this header before any Qt header. #include <vrvUtil/signalslib.h> #include "exampleEmbeddedMainWindow.h" #include <vrvCore/DtEventLoop.h> #include <vrvOsgQt/DtEmbeddedOsgWindow.h> #include <vrvCoreQt/DtQApplicationProvider.h> #include <vrvCoreQt/DtQtDeMainWindow.h> #include <vrvCoreQt/DtQtDeTicker.h> #include <vrvOsgQt/DtSceneGraphTreeWidget.h> #include <vrvCore/DtWindowFactory.h> #include <vrvOsg/vrvOsg.h> #include <vrvOsgQt/vrvOsgQt.h> #include <vrvCore/DtSceneDriver.h> #include <vrvCoreQt/DtStaticFileDialog.h> #include <vrvCore/DtModelDefinition.h> #include <vrvCore/DtDeSharedState.h> #include <vrvCore/DtWindowManager.h> #include <vrvCore/DtScene.h> #include <vrvCore/DtTerrain.h> #include <vrvCore/DtTerrainPatch.h> #include <QtGui/QApplication> #include <QtGui/QtGui> #include <osg/Group> #include <osgDB/ReadFile> #include <osgGA/TrackballManipulator> using namespace makVrv; ExampleEmbeddedMainWindow::ExampleEmbeddedMainWindow() : QMainWindow() , myPluginManager(0) , myDe(0) , myMainOSGWidget(0) , myMiniOsgWidget(0) { createDisplayEngine(); buildGui(); preDisplayEngineInitialize(); initializeDisplayEngine(); postDisplayEngineInitialize(); } ExampleEmbeddedMainWindow::~ExampleEmbeddedMainWindow() { // Delete the widget first. It's dtor unregisters it from the dialog // manager which does a findInstance. Therefore, it has to be deleted // before the DtDe is destroyed. if(mySceneGraphTreeWidget) { delete mySceneGraphTreeWidget; mySceneGraphTreeWidget = 0; } if (myMainOSGWidget) { delete myMainOSGWidget; myMainOSGWidget = 0; } if(myMiniOsgWidget) { delete myMiniOsgWidget; myMiniOsgWidget = 0; } delete myDe; myDe = 0; delete myPluginManager; myPluginManager = 0; } void ExampleEmbeddedMainWindow::preDisplayEngineInitialize() { // Pre initialize functions overrideDisplayEngineFunctionality(); } void ExampleEmbeddedMainWindow::createDisplayEngine() { DtDeConfiguration deConfig; DtDeInitializer init; std::string displayName = DtDisplayConfiguration::DefaultDisplayString; displayName += " 1"; // Configure DtDeInitializer init.setDeMode(DtDeInitializer::MasterMode); init.setDisplayEngineName(displayName); // Configure an observer for channel control makVrv::DtObserverConfiguration observerConfig("Observer 1"); makVrv::DtObserverConfiguration observerConfig2("Observer 2"); makVrv::DtInputDriverConfiguration inputConfig; inputConfig.observerConfigurations().add(observerConfig); inputConfig.observerConfigurations().add(observerConfig2); inputConfig.setOptionalParameter( "windowDependent", "true" ); init.setInputDriverConfiguration( inputConfig ); // Configure DtDeConfiguration std::string wName = makVrv::DtWindowConfiguration::DefaultWindowString; wName += " 1"; DtWindowConfiguration wc(wName); std::string cName = makVrv::DtChannelConfiguration::DefaultChannelString; cName += " 1"; DtChannelConfiguration cc(cName); cc.setObserverName( "Observer 1" ); DtDisplayConfiguration dec(displayName); wc.setWindowType(DtWindowConfiguration::EmbeddedWindow); wc.channelConfigurations().add(cc); std::string wName2 = makVrv::DtWindowConfiguration::DefaultWindowString; wName2 += " 2"; DtWindowConfiguration wc2(wName2); std::string cName2 = makVrv::DtChannelConfiguration::DefaultChannelString; cName2 += " 2"; DtChannelConfiguration cc2(cName2); cc2.setObserverName( "Observer 2" ); wc2.setWindowType(DtWindowConfiguration::EmbeddedWindow); wc2.channelConfigurations().add(cc2); dec.windowConfigurations().add(wc); dec.windowConfigurations().add(wc2); deConfig.displayConfigurations().add(dec); // Set helper pointer. myDe = new DtDe(); myDe->setDeInitializer(init); myDe->setDeConfiguration(deConfig); myPluginManager = new DtPluginManager(*myDe); #ifndef _WIN32 // DI-Guy links in Qt 3, which is incompatible with Qt 4 based applications. // The following code will exclude the DI-Guy plugin for Linux: std::list<std::string> excludePlugins; excludePlugins.push_back("../plugins/release/libvrvDiGuyPlugin.so"); myPluginManager->setExcludedPluginFiles(excludePlugins); #endif myPluginManager->initializePlugins(); } void ExampleEmbeddedMainWindow::overrideDisplayEngineFunctionality() { // Set the display window creator function to use the Adapter widget. DtWindowFactory::instance(*myDe).setCreator( DtWindowConfiguration::EmbeddedWindow, new ExampleEmbeddedMainWindowViewCreator(this)); vrvCoreQt::init(*myDe); vrvOsg::init(*myDe); // Register the qApp with the DtQApplicationProvider. DtQApplicationProvider::instance(*myDe).setQAppInstance(qApp); // Register null with the DtDeMainWindowProvider so that no main window // is ever created. This DtDe instance is embedded in a QMainWindow already. DtDeMainWindowProvider::registerInstance(*myDe, NULL); } void ExampleEmbeddedMainWindow::buildGui() { // Create an IG ticker to tick during Qt's idle time. DtQtDeTickerProvider& tickerProvider = DtQtDeTickerProvider::instance(*myDe); tickerProvider.ticker(this); // this needs an active Display to be hooked up properly DtSceneGraphTreeWidgetCreator* twc = new DtSceneGraphTreeWidgetCreator(*myDe); mySceneGraphTreeWidget = twc->create(this); QDockWidget* dock = new QDockWidget(tr("Scene Tree"), this); dock->setWidget(mySceneGraphTreeWidget); addDockWidget(Qt::LeftDockWidgetArea,dock,Qt::Vertical); setWindowTitle(tr("Embedded Example")); setWindowIcon(QIcon(":/images/Mak-de.png")); createActions(); createMenus(); createToolBars(); createStatusBar(); } void ExampleEmbeddedMainWindow::initializeDisplayEngine() { myDe->initialize(); } void ExampleEmbeddedMainWindow::postDisplayEngineInitialize() { } void ExampleEmbeddedMainWindow::closeEvent(QCloseEvent *event) { event->accept(); } makVrv::DtWindow* ExampleEmbeddedMainWindowViewCreator::create( makVrv::DtDe& de, makVrv::DtWindowConfiguration& wc) { DtEmbeddedOsgWindow* pWindow = 0; DtOsgAdapterQtWidget* pAdapter = 0; osg::GraphicsContext* sharedContext = 0; if(de.display()) { const DtWindowManager::WindowList& windows = de.display()->windowManager().windows(); if(windows.size() > 0) { DtOsgWindow* osgView = dynamic_cast<DtOsgWindow*>(windows.front()); if(osgView) { sharedContext = osgView->graphicsContext(); } } } osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(); traits->doubleBuffer = true; traits->sharedContext = sharedContext; if(wc.name() == "Window 1") { // Set the main OSG widget as the central widget. myWindow->myMainOSGWidget = new DtOsgAdapterQtWidget( de, traits.get(),DtOsgAdapterQtWidget::createFormatFromTraits(traits.get()),myWindow); myWindow->setCentralWidget(myWindow->myMainOSGWidget); pAdapter = myWindow->myMainOSGWidget; } else if(wc.name() == "Window 2") { myWindow->myMiniOsgWidget = new DtOsgAdapterQtWidget( de, traits.get(),DtOsgAdapterQtWidget::createFormatFromTraits(traits.get()),myWindow); QDockWidget* dockMini = new QDockWidget("Mini Widget",myWindow); dockMini->setWidget(myWindow->myMiniOsgWidget); myWindow->addDockWidget(Qt::LeftDockWidgetArea,dockMini,Qt::Vertical); pAdapter = myWindow->myMiniOsgWidget; } if(pAdapter) { pWindow = new DtEmbeddedOsgWindow(de, wc, pAdapter); if(pWindow) { pAdapter->setView(pWindow); } } return pWindow; } void ExampleEmbeddedMainWindow::open() { QString terrainDir = myDe->dePathConfiguration().dataPath().c_str(); terrainDir += "//Terrain"; QString filename = DtStaticFileDialog::getOpenFileName(*myDe,this,tr("Open File"),terrainDir, tr( "All Readable Data Types (*.mtp *.mtd *.mtl *.gdb *medf *.dt0 *.dt1 *.dt2 *.dted *.flt *.c4b *.c7b *.c7l *.shp *.3ds *.osg *.lwo *.obj *.txp);;" \ "MAK Terrain Project (*.mtp *.mtd);;" \ "MAK Terrain Database (*.gdb);;" \ "MAK Stealth Legacy MTL (*.mtl);;" \ "MAK Encrypted Data Format (*.medf);;" \ "DTED (*.dt0 *.dt1 *.dt2 *.dted);;" \ "OpenFlight (*.flt);;" \ "CTDB Version 4 (*.c4b);;" \ "CTDB Version 7 (*.c7b);;" \ "CTDB Version 7L (*.c7l);;" \ "Shape Terrain Data (*.shp);;" \ "Terrapage (*.txp);;" \ "Other 3D Formats (*.3ds *.osg *.lwo *.obj);;" \ "All (*.*);;" )); if(!filename.isEmpty()) { QDir dir; QString relativePath = dir.relativeFilePath(filename); // Create a model definition. std::string modelPath = relativePath.toStdString(); DtModelDefinition modelDef(modelPath); modelDef.setParameter("filename", modelPath); myDe->sharedState().addModelDefinition(modelDef); // Add the model as a terrain patch myDe->scene().terrain().addTerrainPatch(modelDef.name()); } } void ExampleEmbeddedMainWindow::closeFile() { myDe->scene().resetScene(); } void ExampleEmbeddedMainWindow::createActions() { myOpenAction = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); myOpenAction->setShortcut(tr("Ctrl+O")); myOpenAction->setStatusTip(tr("Open an existing file")); connect(myOpenAction, SIGNAL(triggered()), this, SLOT(open())); myCloseAction = new QAction(QIcon(":/images/close.png"), tr("&Close"), this); myCloseAction->setShortcut(tr("Ctrl+C")); myCloseAction->setStatusTip(tr("Close the current file")); connect(myCloseAction, SIGNAL(triggered()), this, SLOT(closeFile())); myExitAction = new QAction(QIcon(":/images/exit.png"),tr("E&xit"), this); //IF you want to quit using a key stroke //exitAct->setShortcut(tr("Ctrl+Q")); myExitAction->setStatusTip(tr("Exit the application")); connect(myExitAction, SIGNAL(triggered()), this, SLOT(close())); } void ExampleEmbeddedMainWindow::createMenus() { myFileMenu = this->menuBar()->addMenu(tr("&File")); myFileMenu->addAction(myOpenAction); myFileMenu->addAction(myCloseAction); myFileMenu->addSeparator(); myFileMenu->addAction(myExitAction); } void ExampleEmbeddedMainWindow::createToolBars() { myFileToolBar = this->addToolBar(tr("File")); myFileToolBar->addAction(myOpenAction); myFileToolBar->addAction(myCloseAction); } void ExampleEmbeddedMainWindow::createStatusBar() { this->statusBar()->showMessage(tr("Ready")); }