18.4. Qt

Introduction

Background

Open Inventor consists of a portable core component and various window system-specific components:

This chapter describes the Open Inventor portable window-system components for the Qt environment, specifically the SoQt classes.

Qt is a cross-platform C++ GUI application framework from Trolltech AS. See www.trolltech.com for more information.

Architecture

Open Inventor was designed to be portable and window system independent. Like OpenGL it uses a large core of system-independent classes and a small set of window system-specific classes. The SoXt classes are specific to the X Windows/ Xt/ Motif environment (Unix/Linux). The SoWin SoWin classes are specific to the Microsoft Windows environment. The SoQt classes are specific to the Qt environment, but Qt is itself window system independent. So the combination of the Open Inventor core, SoQt classes, and Qt allows a single application source code to build and run on many different platforms, including both Unix/Linux and Microsoft Windows.

There is a close correspondence between the SoXt , the SoWin SoWin , and the SoQt classes. Thus, it is very easy to port an SoXt or an SoWin SoWin Inventor program to a portable SoQt program.

SoQt Classes

Introduction

As usual, it is easier to begin with a simple example. Here is a simple Open Inventor program from Chapter 2 of The Inventor Mentor (Example 2.4, “ “Hello, Cone” Using the Examiner Viewer). This program has been translated into Qt by simply replacing the SoXt calls with SoQt calls.

This program works essentially the same as it would with SoXt and SoWin SoWin . Calling SoQt ::init with a string creates a QApplication and its main window, and returns its window handle. The viewer’s window is created as a child of the main window. The “ show ” call makes the various windows visible and the SoQt ::mainLoop provides the Qt event loop.

Example 18.14. “Hello Cone” using SoQt classes

#include <Inventor/Qt/SoQt.h>
#include <Inventor/Qt/SoQtRenderArea.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>

int main(int, char **argv)
{
  // Initialize Inventor. This returns a main window to use.
  // If unsuccessful, exit.
  QWidget *myWindow = SoQt::init(argv[0]);    // pass the app name
    if (myWindow == NULL)
    return 1;

  // Make a scene containing a red cone
    SoSeparator *root = new SoSeparator;
    SoPerspectiveCamera *myCamera = new SoPerspectiveCamera;
    SoMaterial *myMaterial = new SoMaterial;
    root->ref();
    root->addChild(myCamera);
    root->addChild(new SoDirectionalLight);
                                              // Red
    myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
    root->addChild(myMaterial);
    root->addChild(new SoCone);

  // Create a render area in which to see our scene graph.
  // The render area will appear within the main window.
    SoQtRenderArea *myRenderArea = new SoQtRenderArea(myWindow);

  // Make myCamera see everything.
    myCamera->viewAll(root, myRenderArea->getViewportRegion());

  // Put our scene in myRenderArea, change the title
    myRenderArea->setSceneGraph(root);
    myRenderArea->setTitle("Hello Cone");
    myRenderArea->show();

    SoQt::show(myWindow);         // Display main window
    SoQt::mainLoop();             // Main Inventor event loop
    return 0;
}


SoQt Classes

The SoQt class initializes Inventor for use with all supported systems. All of its methods are static convenience functions. Every SoQt class includes all the methods of its corresponding SoWin SoWin and SoXt class. Generally these methods have the same or similar behavior. In a few cases the data types have been changed for the Qt environment. In particular:

SoWin SoWin

SoXt

SoQt

HWND

Window and Widget

QWidget *

MSG

XEvent

QEvent

SoQtComponent

SoQtComponent is the abstract base class for all Open Inventor components. Some of the functions were already defined in the QWidget class but are still defined for compatibility reasons, like show(), hide(), isVisible(), setFullScreen(), or setTitle(). Others are typical Open Inventor component functions like getWidget(), getWidgetName(), getClassName(), etc. The getDisplay() method is for use on Unix only.

Help files are handled differently on Windows and Unix/Linux. On Windows, SoQt opens a CHM help file (VC++ 6.0) or a Help 2.0 file (VC++ 7.1 and newer). On Unix/Linux, it opens the HTML help documentation.

SoQtGLWidget

SoQtGLWidget is the generic component for OpenGL rendering. SoQtGLWidget uses QGLWidget from Qt.

Windows

Unix

Qt

HGLRC

GLXContext

QGLContext

PIXELFORMATDESCRIPTOR

XVisualInfo

QGLFormat

How to Use SoQt in Your Qt Application

This part describes how to implement a Qt application using SoQt classes. Good examples to look at to understand this part are the QtLargeModelViewer or the QtTreeView examples (located in $OIVHOME/src/Inventor/examples/Qt).

  • Initialization of Open Inventor. This is done using one of the two SoQt::init methods:

    void SoQt::init(QWidget *topLevelWidget)
    QWidget *SoQt::init(const char *appName, const char *className = "Inventor")
    
    • Both functions will call SoDB SoDB SoDB ::init(), SoNodeKit::init(), and SoInteraction ::init().

    • The first method assumes you’ve created the QApplication and the mainWidget and receives a handle to this mainWidget as an argument.

    • The second method receives the name of the application which will be used to set the title of the mainWindow as the first argument and the name of the class as the second argument. It creates the QApplication and the mainWidget and returns a handle to this mainWidget. The QApplication object is accessible through the global pointer qApp.

  • Create an Open Inventor render area or viewer. The function getWidget() returns a handle to the widget of these components. It’s then easy to include an Open Inventor component in your application.

  • Use the SoQt:: show () method to make your window visible.

  • Launch Qt’s event loop: SoQt ::mainLoop(). You can also directly call Qt’s event loop: exec().

Note for SoWin SoWin and SoXt users: Qt will delete all the widgets when the application is closed.

Look and Feel

Open Inventor for Qt has been adapted to the Qt user interface guidelines, but at the same time preserves the system-independent “look and feel” of the viewer and editor components. Notice that the distinctive Open Inventor thumb wheel is preserved and the viewer toolbar uses the same button bitmaps as on SoWin SoWin and SoXt .

A render area, material editor, material palette, and color editor

Figure 18.21. A render area, material editor, material palette, and color editor



Qt Designer Plugin

Open Inventor provides a plugin for Qt Designer. This plugin extends the set of available widgets in Qt Designer so that an Open Inventor 3D viewer can easily be integrated into the application’s user interface.

The directory $OIVHOME/OpenInventor/OIV/src/Inventor/examples/Qt/Plugin contains the files necessary to build Qt Designer plugin library, including project and source files:

  • SoQtWidgetPlugin.dsp : project file (Windows only)

  • Makefile: make file (Unix/Linux only)

  • SoQtWidgetPlugin.cxx: source file of the plugin

  • SoQtWidgetPlugin.h: header file of the plugin

  • SoQtWidgetPlugin.pro: Qt project file

On Windows, the plugin DLL is automatically created by the Open Inventor SoQt installer (the tool that builds SoQt after Open Inventor has been installed) and will be placed in the designer plugin directory (for example, %QTDIR%\plugins\designer).

On Unix or Linux, you must build the plugin library yourself, using the supplied makefile. The makefile will copy the library into the designer plugin directory (for example, $(QTDIR)/plugins/designer).

How it works

When the Qt Designer program starts, it loads all the plugin libraries in the Qt plugin directory (e.g., $QTDIR/plugins/designer).

The SoQtWidgetPlugin library will add a new group (Open Inventor) in the toolbox bar and a new item in this group: SoQtWrapper (it must have the same name as the class of the object created).

The tooltip text will be: “Open Inventor Viewer Widget”. And the “What’s this” text will be: “A widget to visualize 3D graphics with Open Inventor”. See Figure 18.22, “ Qt Designer Plugin (tooltip and “What’s this” text)” below.

Qt Designer Plugin (tooltip and “What’s this” text)

Figure 18.22.  Qt Designer Plugin (tooltip and “What’s this” text)



All of these parameters are defined in the SoQtWidgetPlugin class and can be changed. The path to SoQtWrapper.h is also stored in the SoQtWidgetPlugin library.

This plugin will create a Qt form widget that contains, by default, an SoQtExaminerViewer object. These objects will be saved in a “.ui” XML Qt Designer file.

You can replace the Examiner Viewer with a render area or another Inventor viewer in the .cpp file that is generated by the project that loads this “.ui” file. See the Reference Manual for more information on SoQtWrapper .