VTK HelloWorld 项目核心业务流程
项目代码
main.cpp
cpp
#include <QApplication>
#include <QMainWindow>
// Now include VTKWidget
#include "vtkwidget.h"
#include<vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
int main(int argc, char *argv[])
{
// Create QApplication first
QApplication a(argc, argv);
// Create main window
QMainWindow mainWindow;
mainWindow.setWindowTitle("VTK HelloWorld");
mainWindow.resize(800, 600);
// Create VTKWidget and add to main window
VTKWidget *vtkWidget = new VTKWidget(&mainWindow);
mainWindow.setCentralWidget(vtkWidget);
// Show window
mainWindow.show();
return a.exec();
}
vtkwidget.h
cpp
#ifndef VTKWIDGET_H
#define VTKWIDGET_H
#include <QWidget>
#include <QVBoxLayout>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkOpenGLRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <QVTKOpenGLWidget.h>
class VTKWidget : public QWidget
{
Q_OBJECT
public:
explicit VTKWidget(QWidget *parent = nullptr);
~VTKWidget();
private:
// Initialize VTK scene
void initVTK();
QVTKOpenGLWidget *m_pScene;
};
#endif // VTKWIDGET_H
cpp
#include "vtkwidget.h"
#include <QVTKWidget.h>
#include <array>
#include <vtkNew.h>
#include <vtkNamedColors.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkGenericOpenGLRenderWindow.h>
VTKWidget::VTKWidget(QWidget *parent) : QWidget(parent)
{
// Set layout first
QVBoxLayout *layout = new QVBoxLayout(this);
// Initialize VTK scene
initVTK();
// Add QVTKOpenGLWidget to layout
layout->addWidget(m_pScene);
setLayout(layout);
}
VTKWidget::~VTKWidget()
{
}
void VTKWidget::initVTK()
{
m_pScene = new QVTKOpenGLWidget();
vtkNew<vtkNamedColors> colors;
// Set the background color.
double bkg[3] = {0.1, 0.2, 0.4};
colors->SetColor("BkgColor", bkg);
// This creates a polygonal cylinder model with eight circumferential facets
// (i.e, in practice an octagonal prism).
vtkNew<vtkCylinderSource> cylinder;
cylinder->SetResolution(8);
// The mapper is responsible for pushing the geometry into the graphics
// library. It may also do color mapping, if scalars or other attributes are
// defined.
vtkNew<vtkPolyDataMapper> cylinderMapper;
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
// The actor is a grouping mechanism: besides the geometry (mapper), it
// also has a property, transformation matrix, and/or texture map.
// Here we set its color and rotate it around the X and Y axes.
vtkNew<vtkActor> cylinderActor;
cylinderActor->SetMapper(cylinderMapper);
double tomatoColor[3] = {1.0, 0.39, 0.28};
cylinderActor->GetProperty()->SetColor(tomatoColor);
cylinderActor->RotateX(30.0);
cylinderActor->RotateY(-45.0);
// The renderer generates the image
// which is then displayed on the render window.
// It can be thought of as a scene to which the actor is added
vtkNew<vtkRenderer> renderer;
renderer->AddActor(cylinderActor);
renderer->SetBackground(bkg);
// Zoom in a little by accessing the camera and invoking its "Zoom" method.
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(1.5);
vtkSmartPointer<vtkGenericOpenGLRenderWindow> window = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
window->AddRenderer(renderer);
m_pScene->SetRenderWindow(window);
}
背景
项目基于VTK+QT开发
VTK环境安装:VTK-8.2.0版本安装
项目概述
VTK HelloWorld 是一个基于 Qt5 和 VTK 8.2.0 的简单 3D 可视化程序,用于展示如何在 Qt 应用程序中集成 VTK 进行 3D 渲染。
核心业务流程
1. 程序启动流程
启动程序
创建 QApplication
初始化 VTK 模块
创建 QMainWindow
创建 VTKWidget
初始化 VTK 场景
显示主窗口
进入事件循环
2. VTK 场景初始化流程
VTKWidget 构造函数
创建布局
调用 initVTK
创建 QVTKOpenGLWidget
创建 vtkNamedColors
创建 vtkCylinderSource
创建 vtkPolyDataMapper
创建 vtkActor
设置 Actor 属性
创建 vtkRenderer
添加 Actor 到 Renderer
设置背景颜色
重置相机
创建 vtkGenericOpenGLRenderWindow
添加 Renderer 到 RenderWindow
设置 QVTKOpenGLWidget 的 RenderWindow
添加 QVTKOpenGLWidget 到布局
组件关系
1. 类层次结构
QApplication
QMainWindow
VTKWidget
QVTKOpenGLWidget
vtkGenericOpenGLRenderWindow
vtkRenderer
vtkActor
vtkPolyDataMapper
vtkCylinderSource
2. 核心组件职责
| 组件 | 职责 | 来源 |
|---|---|---|
| QApplication | 应用程序主对象,管理事件循环 | Qt5 |
| QMainWindow | 主窗口容器,提供用户界面框架 | Qt5 |
| VTKWidget | 自定义 Widget,集成 VTK 渲染 | 自定义 |
| QVTKOpenGLWidget | VTK 与 Qt 的桥接组件,显示渲染结果 | VTK |
| vtkGenericOpenGLRenderWindow | VTK 渲染窗口,管理渲染过程 | VTK |
| vtkRenderer | 渲染器,管理场景中的对象 | VTK |
| vtkActor | 场景中的可视化对象 | VTK |
| vtkPolyDataMapper | 数据映射器,将数据转换为可视化表示 | VTK |
| vtkCylinderSource | 圆柱体数据源,生成圆柱体几何数据 | VTK |
| vtkNamedColors | 颜色管理工具,提供预定义颜色 | VTK |
技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Qt | 5.14.2 | 图形用户界面框架 |
| VTK | 8.2.0 | 3D 可视化库 |
| C++ | C++11 | 编程语言 |
| qmake | Qt 自带 | 构建工具 |
关键技术点
-
VTK 模块初始化 :使用
VTK_MODULE_INIT宏初始化必要的 VTK 模块,确保渲染功能正常工作。 -
Qt 与 VTK 集成 :使用
QVTKOpenGLWidget作为 VTK 渲染窗口的容器,实现 VTK 渲染结果在 Qt 界面中的显示。 -
3D 场景构建:通过创建数据源、映射器、Actor 和渲染器,构建完整的 3D 渲染场景。
-
内存管理 :使用 VTK 的智能指针
vtkSmartPointer和vtkNew管理 VTK 对象的生命周期,避免内存泄漏。 -
初始化顺序:确保 QApplication 在任何 QWidget 创建之前创建,避免 "QWidget: Must construct a QApplication before a QWidget" 错误。
运行环境要求
- Qt 5.14.2 或更高版本
- VTK 8.2.0 或兼容版本
- C++ 编译器:MSVC 2017 或兼容编译器
- 操作系统:Windows 7 或更高版本
常见问题及解决方案
-
QWidget: Must construct a QApplication before a QWidget:确保 QApplication 在任何 QWidget 创建之前创建,将 VTK 相关的头文件包含和模块初始化移到 QApplication 创建之后。
-
链接错误 :确保在项目配置中包含所有必要的 VTK 库,例如
vtkCommonColor-8.2、vtkGUISupportQt-8.2等。 -
运行时崩溃:确保 VTK 的运行时库(DLL 文件)可访问,将 VTK 安装目录下的 bin 文件夹添加到系统环境变量 PATH 中。
-
编译错误 :确保包含所有必要的头文件,例如
vtkCamera.h、vtkProperty.h等。