VTK 9.4 + QtQuick6从编译到Demo

VTK 9.4 + QtQuick6从编译到Demo

  • 编写这篇博客的主要原因是个人接触到的3D相关开发需求越来越多了,比如在3D Slicer上开发一些简单插件,处理3D数据并显示之类的
  • 其次直接使用OpenGL函数库编写难度又比较大,Slicer的渲染使用了VTK的代码,所以个人也打算进行尝试
  • 个人参加工作后使用的UI技术就是QML,VTK网上看到的示例一般是很旧的Widget,本着学新不学旧的原则,还是坚持使用QML+VTK的方式进行测试开发
  • 博客的测试时间: 2025.05.25

一、基础环境安装

1. Visual Studio 2019

https://docs.vtk.org/en/latest/build_instructions/index.html

  • 没错就是2019, 官方的编译指导说的很重,所以个人也没有去测试其他的编译器类型
  • 微软官方似乎有意减少旧版的编译器使用,如果需要安装还是搜索一些大哥的安装器, 这里贴一个: https://zhuanlan.zhihu.com/p/740245143
    在这里插入图片描述

2. Qt6开发环境

  • Qt Online Installer下载地址: https://download.qt.io/official_releases/online_installers/
  • 选择一个比较新的版本(个人是6.7.0)直接全勾上就行了
  • 可以将Tools中的CMake勾上(如果没有的话)
    在这里插入图片描述

二、开始进行库编译

1. VTK源码下载

  • 在官方下载页面: https://vtk.org/download/
  • 下载Source那个压缩包就可以了,这里贴一下gitlab地址: https://gitlab.kitware.com/vtk/vtk,不是很推荐除非遇上了奇怪的问题需要最新的代码解决
    在这里插入图片描述

2. 开始添加CMake编译参数

这里的官方的编译指导就没有什么特别的指导意义了,由社区以及各种帖子给出,这里给出一些简单说明

  • VTK_QT_VERSION: 指定为6否则容易在自动搜索的时候出错
  • VTK_GROUP_ENABLE_Qt: 开源项目Qt-VTK-viewer中看到的,大意是给Qt编译一些接口,以允许访问VTK的数据结构
  • QML的支持在源码的GUISupport/QtQuick中,其中有个vtk.module的文件描述了其依赖关系(没错不是直接通过cmake组织的,所以编译的时候推荐在CLion中进行,只要参数填对后代码提示可以正常显示,那这个参数就是正确的)
    • GUISupportQtQuick模块依赖于GUISupportQt,所以这两个都需要开启
    • 关于开启方法来自于社区的一个编译bug: https://discourse.vtk.org/t/unable-to-build-vtk-9-4-with-qt-6-8/14857/6,个人看了老半天还是感谢前人探路
  • 最后的两个是Qt的开发环境
    • VTK用到了Qt的一些基础事件需要QtCore
    • Qt6QmlTools则是GUISupportQtQuick生成插件使用的工具
set(VTK_QT_VERSION 6)
set(VTK_GROUP_ENABLE_Qt YES)
set(VTK_MODULE_ENABLE_VTK_GUISupportQt YES)
set(VTK_MODULE_ENABLE_VTK_GUISupportQtQuick YES)
set(Qt6_DIR "D:/Development/Envs/QtEnv/6.7.0/msvc2019_64/lib/cmake/Qt6")
set(Qt6QmlTools_DIR "D:/Development/Envs/QtEnv/6.7.0/msvc2019_64/lib/cmake/Qt6QmlTools")

在这里插入图片描述

  • 当Clion能够正常跳转类、函数的时候,说明参数填写正确
    在这里插入图片描述

3. 编译以及安装

  • 编译的话简单点击Build All即可,编译过程比较长只要能通过说明编译成功,如果中间失败的话需要自寻大佬解决
    在这里插入图片描述
  • 这里贴一些安装命令,以方便包管理
cd D:\Development\Envs\PACS-env\Archive\VTK-9.4.2\cmake-build-debug
cmake --install . --prefix=D:\Development\Envs\vtk-9.4.2-debug

在这里插入图片描述
在这里插入图片描述

  • 请注意此文件夹,这是成功的标志
  • 还有就是别忘记把bin目录加入环境变量中

三、从源码中复现Demo

1. 创建基础Quick项目

在这里插入图片描述

  • 一路按下去,无中文路径即可,然后开始添加VTK支持
  • 此修改遵守示例: Examples/GUI/QML/QtQuickChartsOn3DScene/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(01-VTKQtBuildVertify VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

### 添加VTK支持, 模块内容来自Example ########
set(VTK_DIR "D:/Development/Envs/vtk-9.4.2-debug/lib/cmake/vtk-9.4")
find_package(VTK
    COMPONENTS
        CommonCore
        CommonColor
        ChartsCore
        GUISupportQtQuick
        RenderingContextOpenGL2
)
#####################
find_package(Qt6 REQUIRED COMPONENTS Quick)

qt_standard_project_setup()
qt_add_executable(app01-VTKQtBuildVertify
    main.cpp
)

qt_add_qml_module(app01-VTKQtBuildVertify
    URI app01-VTKQtBuildVertify
    VERSION 1.0
    QML_FILES
        Main.qml
)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
set_target_properties(app01-VTKQtBuildVertify PROPERTIES
#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01-VTKQtBuildVertify
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(app01-VTKQtBuildVertify
    PRIVATE Qt6::Quick ${VTK_LIBRARIES}
)
########### VTK模块初始化 ##############
vtk_module_autoinit(
        TARGETS app01-VTKQtBuildVertify
        MODULES ${VTK_LIBRARIES}
)
######################################
include(GNUInstallDirs)
install(TARGETS app01-VTKQtBuildVertify
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

2. 允许QML编辑器对VTK进行代码提示

参考了GUISupport/QtQuick/qml/QQmlVTKPlugin.h

  • 官方说直接添加第二章最后编译出来的QML文件夹到环境变量即可,但个人尝试无效
    在这里插入图片描述
  • 下列是个人成功的方法,将编译出的插件目录直接贴到Qt开发的QML目录即可
    在这里插入图片描述

3. UI部分逻辑

完成2的步骤后,import VTK就不会报错了

  • 注意这个import后面的数字应该是你贴到QtQML组件的文件夹,个人查看里面的qmltypes文件时发现其描述的9.1,倍感迷惑
  • 并且在qmltypes中,qml可以调用的组件只有三个,所以推荐大家直接放弃在QML中直接绘制逻辑的想法,求大佬封装一个牛逼的Quick3D库,或者推荐推荐也行
import QtQuick
import QtQuick.Controls
import VTK 9.4

// M300的可能解决方案: https://forum.qt.io/topic/92025/unknown-component-m300-for-custom-qml-class

Window {
    width: 800
    height: 600
    visible: true
    title: qsTr("Hello World")

    Row{
        Button{
            width: 200
            height: 40
            text: "hhhhhh"
            onClicked: {
                console.log("hhhhhhh")
            }
        }
        Button{
            width: 200
            height: 40
            text: "hhhhhh"
            onClicked: {
                console.log("hhhhhhh")
            }
        }
        Button{
            width: 200
            height: 40
            text: "hhhhhh"
            onClicked: {
                console.log("hhhhhhh")
            }
        }
    }

    VTKRenderWindow{
        id: vtkWindow
        // anchors和width,height一样,无效,即便存在父对象
        // 源码的sync()函数似乎直接设置成了窗口大小
        // anchors.fill: parent
        width: 100
        height: 100
    }

    VTKRenderItem{
        objectName: "ConeView"
        x: 200
        y: 200
        width: 200
        height: 200
        renderWindow: vtkWindow
    }
}

4. main文件部分

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "QQuickVTKItem.h"
#include "QQuickVTKRenderItem.h"
#include "vtkPolyDataMapper.h"
#include "vtkConeSource.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQuickVTKItem::setGraphicsApi();

    // 等价于使用环境变量QML2_IMPORT_PATH
    // https://doc.qt.io/qt-5/qtqml-syntax-imports.html#qml-import-path
    QQmlApplicationEngine engine;
    // engine.addImportPath("D:/Development/Envs/vtk-9.4.2-debug/lib/qml/VTK.9.4");
    // qDebug() << "Import Path List: "
    //          << engine.importPathList();

    // load ui
    const QUrl url(QStringLiteral("qrc:/app01-VTKQtBuildVertify/Main.qml"));
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.load(url);

    // Fetch the QQuick window using the standard object name set up in the constructor
    QObject* topLevel = engine.rootObjects().value(0);
    QQuickVTKRenderItem* qquickvtkItem = topLevel->findChild<QQuickVTKRenderItem*>("ConeView");

    // Create a cone pipeline and add it to the view
    vtkNew<vtkActor> actor;
    vtkNew<vtkPolyDataMapper> mapper;
    vtkNew<vtkConeSource> cone;
    mapper->SetInputConnection(cone->GetOutputPort());
    actor->SetMapper(mapper);
    qquickvtkItem->renderer()->AddActor(actor);
    qquickvtkItem->renderer()->ResetCamera();
    qquickvtkItem->renderer()->SetBackground(0.5, 0.5, 0.7);
    qquickvtkItem->renderer()->SetBackground2(0.7, 0.7, 0.7);
    qquickvtkItem->renderer()->SetGradientBackground(true);
    qquickvtkItem->update();

    return app.exec();
}

5. 最后效果

3,4的实现参考了源码的GUISupport/QtQuick/QQuickVTKRenderWindow.h中的注释

在这里插入图片描述

  • 虽然成功完成了一个Demo的制作和显示,但确实又诸多不足
  • 如果大家跟着做后会发现,QQuickVTKRenderWindow,QQmlVTKPlugin均已经被标记了遗弃标签,并且现在的代码是直接在事件循环前添加的,也就是运行期间无法修改
  • 所以本博客将这次试错定义为一个测试模块是否正确编译的Demo
  • 正常开发的话,还是得看看社区大佬的实现,否则过于玩具了

四、没有解决的问题

在试错过程中发现的一些恶性问题,如果有大神,评论区指点下

1. QQuickVTKRenderWindow

  • 无法正确调整组件大小,会直接覆盖整个界面
    • 源码中的sync()函数似乎直接将整个窗体作为了绘制对象
  • 然后有种Qt绘制到了VTK上,而不是VTK被QML的容器接管的奇妙现象

在这里插入图片描述

2. QML编辑器M300问题

  • 没有尝试过纯QQuickItem的发布方式,个人只能保证导入VTK的时候以及运行的时候不报错,不知道大神有没有解决方案

参考

  • https://discourse.vtk.org/t/qml-vtkrenderwindow-inside-a-rectangle/11850
  • https://github.com/martijnkoopman/Qt-VTK-viewer/blob/master/doc/Build-VTK.md
  • https://discourse.vtk.org/t/unable-to-build-vtk-9-4-with-qt-6-8/14857/6
  • https://forum.qt.io/topic/92025/unknown-component-m300-for-custom-qml-class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tacom_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值