QML渲染VTKRenderWindow
最近由于工作需要,入坑了VTK, 再加上本人从工作以来,做软件界面这方面,一直玩儿的都是qml那套东西,widget之前也玩儿过,但是真心觉得widget太麻烦了。
在一个就是目前网上关于qml加载VTK窗口的资料太少了,逼得没办法,只有去VTK官网的论坛上看看洋鬼子是咋玩儿的
题外话说完了,下面直接开始主题:
开发环境:Qt5.15.2, win10,MSVC2019 64位, VTK9.2(8.2版本官方没有支持qml, 9.1版本好像可以? 没试过哈 )
哦对了,本人学艺不精,没办法详细给出qml是怎么怎么加载出VTK窗口的,反正这么写就可以了(淦!)
1.首先,第一步:在main.cpp中,定义QApplication 之前,先调用QQuickVTKRenderWindow::setupGraphicsBackend();
int main( int argc, char **argv )
{
//定义app之前调用一次,别问我为啥,问就是官方文档上写的,我也不知道
QQuickVTKRenderWindow::setupGraphicsBackend();
QApplication app( argc, argv );
QQmlApplicationEngine engine;
}
2.然后注册三个类(或者两个?QQuickVTKInteractiveWidget这个类注册了但是好像没有用起来)
qmlRegisterType<QQuickVTKRenderWindow>("VTK", 9, 2, "VTKRenderWindow");
qmlRegisterType<QQuickVTKRenderItem>("VTK", 9, 2, "VTKRenderItem");
qmlRegisterType<QQuickVTKInteractiveWidget>("VTK", 9, 2, "VTKWidget");
3.加载main.qml文件
engine.load( "qrc:/main.qml" );
main.qml文件内容如下:
import QtQuick 2.15
import QtQuick.Controls 2.15
import VTK 9.2
ApplicationWindow {
width: 500
height: width
visible: true
VTKRenderWindow{
id: vtkwindow
z: 10
//注意这个objectName, 等会要用到!!!!! x1
objectName: "renderWindow"
width: parent.width * 0.9
height: width
anchors.centerIn: parent
}
VTKRenderItem{
id: coneViewItem
z: 10
//注意这个objectName, 等会要用到!!!!! x2
objectName: "ConeView"
anchors.fill: vtkwindow
renderWindow: vtkwindow
focus: true
}
}
最后,我们可以来看看完整的main.cpp 的内容
int main( int argc, char **argv )
{
QQuickVTKRenderWindow::setupGraphicsBackend();
QApplication app( argc, argv );
QQmlApplicationEngine engine;
qmlRegisterType<QQuickVTKRenderWindow>("VTK", 9, 2, "VTKRenderWindow");
qmlRegisterType<QQuickVTKRenderItem>("VTK", 9, 2, "VTKRenderItem");
qmlRegisterType<QQuickVTKInteractiveWidget>("VTK", 9, 2, "VTKWidget");
engine.load( "qrc:/main.qml" );
//用一个立方体来测试
vtkNew<vtkActor> actor;
vtkNew<vtkPolyDataMapper> mapper;
auto cone = vtkSmartPointer< vtkCubeSource >::New();
cone->SetXLength( 20 );
cone->SetYLength( 40 );
cone->SetZLength( 60 );
cone->Update();
mapper->SetInputConnection(cone->GetOutputPort());
actor->SetMapper(mapper);
auto qquickvtkItem = engine.rootObjects().first()->findChild< QQuickVTKRenderItem* >( "ConeView" );
auto vtkRender = qquickvtkItem->renderer();
vtkRender->AddActor( actor );
vtkRender->SetBackground(0.5, 0.5, 0.7);
QQuickVTKRenderWindow* renderWindow = engine.rootObjects().first()->findChild< QQuickVTKRenderWindow* >( "renderWindow" );
renderWindow->renderWindow()->Render();
return app.exec();
}
最后,直接编译运行, 就加载出立方体模型出来了,并且亲测支持任意 vtkInterActorStyle的操作,例如缩小放大,移动和旋转
tips:
1.值得注意的是,立方体Actor是动态加载进去的,通过qml中,定义的 objectName 获取对应的 vtkRender 对象指针,记录该指针可方便后续的一些自定义操作
auto qquickvtkItem = engine.rootObjects().first()->findChild< QQuickVTKRenderItem* >( "ConeView" );
//获取到render对象指针
auto vtkRender = qquickvtkItem->renderer();
//同理可获取到RenderWindow对象指针
QQuickVTKRenderWindow* renderWindow = engine.rootObjects().first()->findChild< QQuickVTKRenderWindow* >( "renderWindow" );
renderWindow->renderWindow()->Render();