更多参见:HOOPS学习笔记
以下部分,说明如何使用QtGUI工具包和HOOPS 3D应用程序框架构建应用程序。首先回顾编译/链接,然后讨论各个组件对象的关系,然后概述正确创建和初始化对象以及启动Qt事件循环所需的编程步骤。
开发人员应该首先编译、链接和运行基本的qt_simple应用程序,作为其应用程序的起点。
qt_simple的可读源代码位于HOOPS/3dAF安装路径/demo/qt/qt_simple目录中,qt v4变体位于/demo/qt/qt_simpl目录中。
qt_simple假设你对Qt工具包、HOOPS/3dGS和HOOPS/MVO有一定的了解。
Qt工具包的Signals and Slots机制需要一个预编译步骤来构建特殊的源文件。Qt元对象编译器(MOC)作为Qt工具包的一部分提供,必须在编译步骤之前使用。有关更多信息,请参阅Qt文档。
在一起编译HOOPS/Qt和HOOPS/MVO源代码时,必须有以下定义:
一般定义
IS_QT // All HOOPS/Qt applications
特定于windows系统
IS_WIN // Applications built with HOOPS/Qt for MS Windows IS_X11 // Applications built with HOOPS/Qt for UNIX
在UNIX上使用OpenGL
USE_GLX_VISUAL // Applications built with HOOPS/Qt for UNIX that will use OpenGL; i.e., also IS_X11
HOOPS/Qt Widget提供清晰的源代码直接添加到应用程序的源代码库中。因此,没有特殊的HOOPS/Qt库可与项目链接
这一部分讨论不同版本QT对象与HOOPS/3dAF组件之间的关系。使用这两个工具包构建应用程序时,最少需要使用每个组件中的以下对象。
只有一个QApplication&至少QMainWindow(或派生类)
至少一个HQWidget(您通常会创建一个从HQWidget派生的自定义Widget)
HBaseModel、HBaseView,一个从HBaseOperator派生的运算符类。想要实现几何体选择的应用程序还需要一个HSelectionSet对象。这些对象都由私有数据成员连接,私有数据成员采用以下方式存储指向其他对象的指针:
使用面向对象的GUI框架(如Qt)编程包括创建一组对象,定义它们的连接方式、发送和接收消息的方式,然后启动框架的事件循环。使用Qt和HOOPS/3dAF构建应用程序特别需要以下步骤:
对于任何使用Qt的GUI应用程序,无论应用程序有多少个窗口,都只有一个QApplication对象。它可以通过QApplication.h中声明全局变量a来访问、 其必须在创建任何其他Qt对象之前被初始化。qt_simple示例在函数main()中执行此操作:
int main( int argc, char **argv )
{
...
// Create the one QApplication object
QApplication * a = new QApplication(argc,argv);
...
}
QApplication对象属性必须配置颜色分配和GUI样式。对于Qt/HOOPS应用程序,颜色分配必须设置为“ManyColor”。GUI样式用于创建Qt GUI的视觉外观和默认行为,通常选择Motif或Windows样式。
应该创建一个HQApplication,使用接受指向Qt QApplication对象指针的构造函数。qt_simple示例在函数main()中执行此操作:
int main( int argc, char **argv )
{
...
if(argc == 2)
HQApplication * ha = new HQApplication(a, argv[1]);
else
HQApplication * ha = new HQApplication(a);
...
}
HQApplication对象应创建任何Qt GUI对象,以便在初始化期间将其作为父对象。qt_simple示例在HQApplication对象通过调用其私有方法HQApplication::load()初始化时执行此操作.
可以根据需要创建尽可能多的HQWidget对象来实现GUI的设计。这些很可能是由顶级Qt Widget(如QMainWindow或QDialog)的构造函数创建的。qt_simple示例在HQApplication对象通过调用其私有方法HQApplication::load()初始化时执行此操作:
void HQApplication::load(const char * filename)
{
...
SimpleHQWidget * my_widget = new SimpleHQWidget(qframe, "SimpleHQWidget", filename);
...
}
必须在应用程序代码块中声明和初始化一个全局指针。qt_simple示例在文件main.cpp中执行全局声明,并在函数main()的主体中执行初始化:
// Create a global pointer to HOOPS/Qt class HQDeleter
HQDeleter * deleter=0;
int main( int argc, char **argv )
{
...
// Create an HQDeleter object and initialize the global pointer
deleter = new HQDeleter();
...
}
在应用程序main()函数中声明并初始化一个指向HOOPS/MVO HDB对象的全局指针。qt_simple示例示例:
int main( int argc, char **argv )
{
m_pHDB = new HDB();
m_pHDB->Init();
...
}
可以根据需要创建多个HBaseModel对象。qt_simple示例为每个SimpleHQWidget对象创建一个(即,存在HBaseModel到SimpleHQWidget对象的一对一映射),并在SimpleHQDWidget构造函数中这样做。
SimpleHQWidget::SimpleHQWidget(QWidget* parent, const char* name, const char * filename) : HQWidget( parent, name )
{
m_pHBaseModel = new HBaseModel();
m_pHBaseModel->Init();
...
}
可以根据需要创建多个HBaseView对象,通常为每个HQWidget创建一个HBaseView对象。HBaseView需要在创建对象时向其构造函数传递有效的窗口id和颜色映射;用于将HOOPS/3dGS输出驱动程序实例连接到Qt QWidget。这要求在创建HBaseView对象之前,HBaseView将连接到的QtWidget必须已经存在。
HBaseView对象应该在重载的HQWidget::Init()方法中创建和初始化。基类HQWidget在其HQWidget::paintEvent方法中第一次调用HQWidget::Init()方法,这首先确保该Widget是活动的,因而Window ID是有效的,并且可以创建HBaseView对象。下面是qt_simple示例:
void SimpleHQWidget::Init()
{
m_pHView = new HBaseView(m_pHBaseModel, NULL, NULL, NULL, GetWindowId(), GetColorMap(), GetClipOverride());
m_pHView->Init();
...
}
HBaseView类有一个成员HBaseView::m_pOperator,它是指向HBaseOperator对象的指针。应在View初始化期间创建默认运算符。qt_simple示例在重载的HQWidget::Init()初始化m_pOperator:
void SimpleHQWidget::Init()
{
...
m_pHView->SetCurrentOperator(new HOpCameraOrbit(m_pHView));
...
}
可以根据需要创建多个HSelectionSet对象,但通常有HSelectionSet到HBaseView对象映射为一对一映射。
qt_simple示例不创建HSelectionSet对象,因为不提供任何选择支持。
这是通过调用QApplication的方法QApplication::exec()来执行的。请参阅qt_simple示例的main()函数。