Qt step-by-step
 
 
 

Install Qt

MotionBuilder 2011 use QT 4.7 LGPL built with MS VS 2008 with SP1. To develop Mobu ORSDK plugin with QT, you must get a QT open source built by VS 2008.

New way

Download the QT source. Double click to install.

Old way

Download the QT source code built by MingW. Recompile it using VS 2008. It can take a long time. Detail see below:

32-bit Qt setup

  • Download and run the Qt Framework installer (qt-win-opensource-4.7.0-mingw.exe). Usually it installs to C:\Qt\4.7.0.
  • In Visual Studio 2008, choose Tools > Visual Studio Command Prompt.
  • Change directory to C:\Qt\4.7.0 (or where it was installed), and at the prompt type: configure.
  • When prompted for the license type, choose "o" (open source) to build Qt with the LGPL license.
  • When the configuration has finished, at the same prompt type: nmake. This compiles Qt, and can take a very long time, possibly hours.
  • If you have a 64-bit machine, you may optionally setup Qt for building 64-bit plugins.

64-bit Qt setup

  • 64-bit DLLs and binaries must be in their own directory. If you already compiled 32-bit Qt, then install qt-win-opensource-4.7.0-mingw.exe in an additional separate directory, e.g. C:\Qt\4.7.0_x64. Ensure the bin directory of your Qt distribution includes qmake.exe and moc.exe.
  • Windows Start > Programs > Microsoft Visual Studio 2008 > Visual Studio Tools > Visual Studio 2008 x64 Cross Tools Command Prompt.
  • cd to C:\Qt\4.7.0_x64 (or where it was installed) and at the prompt type: configure
  • When prompted for the license type, choose "o" (open source) to build Qt with the LGPL license.
  • When the configuration has finished, at the prompt type: nmake.

Set up Qt environment

To compile/link/compile uic and moc, you must define the following environment variables to to point to Qt header files, Qt.lib, and Qt tools like moc.exe.

FB_QT_BIN_DIR
Directory containing moc.exe and uic.exe. These process the XML created by QT Assistant, e.g. C:\Qt\4.7.0\bin. Same path for 32 bits or 64 bits.
FB_QT_INCLUDE_DIR
Directory containing the Qt include file, e.g. C:\Qt\4.7.0\include.
FB_QT_LIB_32_DIR
Required for building plugins for 32-bit MotionBuilder. Points to the directory containing the Qt .lib files, e.g. C:\Qt\4.7.0\lib.
FB_QT_LIB_64_DIR
Required for building plugins for 64-bit MotionBuilder. Points to the directory containing the Qt .lib files, e.g. C:\Qt\4.7.0_x64\lib.

Create Qt Project

  1. Create a Qt library project.
  2. Set project's properties:
    Properties Values
    C/C++ > General > Additional Include Directories ..\..\..\..\include;..\..\..\..\include\fbxsdk;$(FB_QT_INCLUDE_DIR);$(FB_QT_INCLUDE_DIR)\Qt;$(FB_QT_INCLUDE_DIR)\QtCore;$(FB_QT_INCLUDE_DIR)\QtGui; .\GeneratedFiles
    Linker > General > Additional Library Directories ..\..\..\..\lib\$(PlatformName);$(FB_QT_LIB_64_DIR)
    Linker > Input > Additional Dependencies fbsdk.lib opengl32.lib glu32.lib QtCore4.lib QtGui4.lib
    Debugging > Command D:\devcopy\MB\Opus\bin\x64\motionbuilder.exe
    Debugging > Intermediate Directory ..\..\..\..\..\obj\$(PlatformName)\plugins\$(ProjectName)
    Noteyou may need to add or delete "..\" to make sure the path is correct to find the files or folders.

Create Qt GUI class

  1. Create xxx QT GUI class. Make it inherit from Qt4GuiClass. See below. Then the solution should be like below:
  2. Double click xxx.ui. Edit it in QT Designer. You can set the button name to buttonCreateCube, horizontal slider name to sliderChangeCubeSize. Then save it.
  3. Change xxx.h file follow below steps in code:
    #ifndef XXX_H
    #define XXX_H
    
    #include <QWidget>
    #include "ui_xxx.h"
    #include <fbsdk/fbsdk.h>            // 1. reference fbsdk file
    
    class xxx : public QWidget
    {
        Q_OBJECT
    
    public:
        xxx(QWidget *parent = 0);
        virtual ~xxx();                 // 2. add virtual to keep safe
    
    public slots:                       // 3. add slots.  <slotName> = on_<controlName>_<singleName>
        void on_buttonCreateCube_clicked();
        void on_sliderChangeCubeSize_valueChanged (int);
    
    private:
        Ui::xxx ui;
        FBModel* mCube;                 // 4. define a FBModel for cube
    };
    
    #endif // XXX_H
    
  4. Change xxx.cpp file.
    #include "xxx.h"
    
    xxx::xxx(QWidget *parent)
        : QWidget(parent), mCube(NULL)  // 1. remeber to set mCube to NULL
    {
        ui.setupUi(this);
    }
    
    xxx::~xxx()
    {
        // 2. remember to release mCube
        if(NULL != mCube)
        {
            delete mCube;
            mCube = NULL;
        }
    }
    
    // 3. declare 2 slots
    void xxx::on_buttonCreateCube_clicked()
    {
        if ( NULL == mCube)
        {
            mCube = new FBModelCube( "My FB Cube" );
            mCube->Scaling = FBVector3d( 20, 20, 20 );
            mCube->Show = true;
    
            // get control by ui.<controlName>  NEW!
            ui.sliderChangeCubeSize->setMaximum(100);           
            ui.sliderChangeCubeSize->setMinimum(1);
            ui.sliderChangeCubeSize->setValue( 20 );
            ui.buttonCreateCube->setDisabled( true );
        }
    }
    
    void xxx::on_sliderChangeCubeSize_valueChanged (int pValue)
    {
        if ( NULL != mCube )
        {
            FBVector3d lScaling( pValue, pValue, pValue );
            mCube->Scaling = lScaling;
        }
    }
    

Create FBTool Child Class

  1. Change qtsample.h file
    #ifndef QTSAMPLE_H
    #define QTSAMPLE_H
    
    // 1. reference fbsdk
    // important to include all Qt file BEFORE sdk file. This will remove lots of useless warnings/errors.
    #include "qtsample_global.h"
    #include <fbsdk/fbsdk.h>                        
    
    // 2. declare 2 macro
    #define QTSAMPLE__CLASSNAME        QtSample     
    #define QTSAMPLE__CLASSSTR        "QtSample"
    
    // 3. inherit from FBTool and declare methods/fields below
    class QTSAMPLE_EXPORT QtSample : public FBTool  
    {
        FBToolDeclare( QtSample, FBTool );
    
    public:
        virtual bool FBCreate();
        virtual void FBDestroy();
    
    private:
        void UICreate();
        void UIConfigure();
    
    private:    
        FBWidgetHolder mQtHolder;
    };
    
    #endif // QTSAMPLE_H
    
  2. Change the qtsample.cpp file.
    // 1. reference xxx.h and fbconsole.h
    // 1. reference xxx.h and fbconsole.h
    #include "xxx.h"
    #include "qtsample.h"
    #include <fbsdk/fbconsole.h>
    
    // 2. registration defines
    #define QTSAMPLE__CLASS    QTSAMPLE__CLASSNAME
    #define QTSAMPLE__LABEL    "Qt Sample"
    #define QTSAMPLE__DESC     "This is a Qt sample with OpenReality SDK to create a plugin for MotionBuilder."
    
    // 3. FiLMBOX implementation and registration
    FBToolImplementation(    QTSAMPLE__CLASS    );
    FBRegisterTool(      QTSAMPLE__CLASS,
                         QTSAMPLE__LABEL,
                         QTSAMPLE__DESC,
                         FB_DEFAULT_SDK_ICON );    // Icon filename (default=Open Reality icon)
    
    // 4. create UI (e.g. xxx) in parent widget. 
    void* CreateQtTestWidget( void* pParent )
    {    
        xxx* newUI = new xxx( (QWidget*)pParent );
        return newUI;
    }
    
    
    // 5. create UI holder and UI xxx.
    bool QtSample::FBCreate()
    {
        // set parent UI start size
        StartSize[0] = 400;
        StartSize[1] = 300;
    
        // Create/reset/manage UI
        UICreate    ();
        UIConfigure    ();
    
        return true;
    }
    
    void QtSample::FBDestroy()
    {}
    
    void QtSample::UICreate()
    {    
        Region.X = 300;
        Region.Y = 300;
        Region.Width = 400;
        Region.Height = 900;    
    
        // this section shows how to embed a native Qt Widget using a KtWidgetHolder.
        AddRegion( "QtHolder", "QtHolder",
            5,    kFBAttachLeft, "", 1.0,
            5, kFBAttachTop, "", 1.0,
            5, kFBAttachRight, "", 1.0,
            350, kFBAttachNone, "",1.0 );
    
        // Set the creator widget into our holder, when need the QWidget will be instantiated.
        mQtHolder.SetCreator( CreateQtTestWidget );
        SetControl( "QtHolder", mQtHolder );
    }
    
    
    void QtSample::UIConfigure()
    {}
    

Create library entry point

Create qtsample_tool.cpp, we are going to create DLL entry point in this file.

// Library declarations.
// Contains the basic routines to declare the DLL as a loadable library.

#include <fbsdk/fbsdk.h>

#ifdef KARCH_ENV_WIN
#include <windows.h>
#endif

// Library declaration.
FBLibraryDeclare( qtsample )
{
    FBLibraryRegister( QtSample );
}
FBLibraryDeclareEnd;

// Library functions.
bool FBLibrary::LibInit()        { return true; }
bool FBLibrary::LibOpen()        { return true; }
bool FBLibrary::LibReady()        { return true; }
bool FBLibrary::LibClose()        { return true; }
bool FBLibrary::LibRelease()    { return true; }

Run!

After compiling QtSample project, if you can see below files generated in output folder, then the plugin has been generated successfully. You can run the project now.

  1. Click the "Qt Sample" button.
  2. Pop out "Qt Sample" dialog.
  3. Click "Create Cube" to create the cube. Drag the slider to change cube's size.