QML加载VTK窗口

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();

2. 尽可能的在qml中,把 VTKRenderWindow 和 VTKRenderItem 对象的 Z 值设置的高一点,否则会被更高层级的控件把鼠标事件给拦截了

最后,各位VTK大佬帮忙看看这样玩儿能不能行,欢迎提意见,哈哈!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值