Ubuntu20.04下QT5.15.2配置QVTKOpenGLNativeWidget控件并在QT中显示VTK窗口

操作系统:Ubuntu 20.04
QT: 5.15.2
VTK : 9.0.1

一、QT5.15.2配置QVTKOpenGLNativeWidget控件

1.1 下载安装VTK9.0.1

具体方法和配置按照我之前的文章进行,使用CMKE进行编译VTK,且要编译release版本,否则不会生成QVTKOpenGLNativeWidget所需要的动态库libQVTKWidgetPlugin.so

1.2 在QT中显示VTK渲染窗口

网上有很多方法很多案例使用qt+vtk的时候用QVTKWidget、QVTKWidget2、QVTKOpenGLWidget、QVTKOpenGLNativeWidget,容易把人弄混。我也是看了这篇文章之后才弄清楚https://blog.csdn.net/a15005784320/article/details/99460999

QVTKWidget、QVTKOpenGLWidget、QVTKOpenGLNativeWidget、QVTKWidget2 区别

这几个控件名指的都是VTK在QT中的控件类型
在这里插入图片描述

这几个widget怎么使用:
每个widget都提供了不同的功能以及不同的API,但是widget的创建以及使用基本一样。
    1)实例化widget
    2)指定渲染窗口交互器
    3)创建回调函数(qt里就直接绑定信号和槽)
    4)创建模型,并与widget关联
    5)激活widget
    6)反激活widget

这几个widget的关系:
在这里插入图片描述
到底应该用那个widget:

放弃使用QVTKWidget。
  包含QVTKOpenGLWidget的VTK的第一个版本是VTK 8.0.0!
  如果你是Qt5.4以前,请使用QVTKWidget2。
  如果你是Qt5.4以后,vtk8.1X及以前 请使用QVTKOpenGLWidget。
  如果你是Qt5.4以后,vtk8.2X 请使用QVTKOpenGLNativeWidget。

比如你有QVTKWidget的程序,直接替换成QVTKWidget2(根据版本定),以此向后类推。

为什么自己用时候还要保留vtk8.1X:

为什么自己用时候还要保留vtk8.1X,因为vmtk官方说明仅支持vtk8.1X及以前,vtk8.2X不确定。虽然vtk8.2X+vmtk可以使用,但可能有隐藏bug。
————————————————
原文链接:https://blog.csdn.net/a15005784320/article/details/99460999

1.3 在QT中配置VTK控件

安裝完VTK之后使用sudo find / -name libQVTKWidgetPlugin.so找到动态链接库的路径;

把ibQVTKWidgetPlugin.so复制到QT的安装目录下:

/home/username/Qt/5.15.2/gcc_64/plugins/designer
/home/username/Qt/Tools/QtCreator/lib/Qt/plugins/designer

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

然后独立的QT Designer和QT creator 中包含的Designer左侧栏目下方就有了QVTKWidget,这里叫是叫QVTKWidget,后面需要根据自己使用的VTK版本和QT版本来修改为QVTKWidget、QVTKOpenGLWidget、QVTKOpenGLNativeWidget、QVTKWidget2 ,不然的话直接拖入到designer界面中后会报错;
在这里插入图片描述

1.4 配置VTK控件

1.4.1 创建一个新的项目
在这里插入图片描述

构建系统选择CMake;
在这里插入图片描述在这里插入图片描述

然后一直点点点直到完成,打开widget.ui文件;

从左侧栏目中拖入QVTKWidget到widget.ui 的界面中,即设置用于渲染VTK模型的窗口;
在这里插入图片描述

此时可以看到该控件类的类类型为QVTKWidget;
在这里插入图片描述

保存,回到左侧的的编辑代码界面,此时widget.cpp文件中会出现报错;
在这里插入图片描述
error :'QVTKWidget.h' file ot found 因为我的vtk版本是VTK9.0.1,是找不到QVTKWidget.h这个文件的;

1.4.2 修改CMakeLists.txt 配置VTK相关头文件 以及 动态链接库篇;

cmake_minimum_required(VERSION 3.5)

project(LastTest LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check https://doc.qt.io/qt/deployment-android.html for more information.
# They need to be set before the find_package( ...) calls below.

#if(ANDROID)
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
#    if (ANDROID_ABI STREQUAL "armeabi-v7a")
#        set(ANDROID_EXTRA_LIBS
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
#    endif()
#endif()

find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
FIND_PACKAGE(VTK REQUIRED)
set(PROJECT_SOURCES
        main.cpp
        widget.cpp
        widget.h
        widget.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(LastTest
        ${PROJECT_SOURCES}
    )
else()
    if(ANDROID)
        add_library(LastTest SHARED
            ${PROJECT_SOURCES}
        )
    else()
        add_executable(LastTest
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(LastTest PRIVATE Qt${QT_VERSION_MAJOR}::Widgets ${VTK_LIBRARIES})

实际上就改了两个地方:

FIND_PACKAGE(VTK REQUIRED)

target_link_libraries(LastTest PRIVATE Qt${QT_VERSION_MAJOR}::Widgets ${VTK_LIBRARIES})

1.4.3 点击左侧的widget.ui,然后右键选择用文本编辑器打开;此时可以直接修改widget.ui的内容;
widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QVTKWidget" name="qvtkWidget">
   <property name="geometry">
    <rect>
     <x>210</x>
     <y>110</y>
     <width>401</width>
     <height>341</height>
    </rect>
   </property>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>QVTKWidget</class>
   <extends>QWidget</extends>
   <header>QVTKWidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

把其中的QVTKWidget修改为QVTKOpenGLNativeWidget

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QVTKOpenGLNativeWidget" name="qvtkWidget">
   <property name="geometry">
    <rect>
     <x>210</x>
     <y>110</y>
     <width>401</width>
     <height>341</height>
    </rect>
   </property>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>QVTKOpenGLNativeWidget</class>
   <extends>QWidget</extends>
   <header>QVTKOpenGLNativeWidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

此时界面中的VTK控件类型就变成了QVTKOpenGLNativeWidget;
在这里插入图片描述

保存;
此时再点击左下角的运行,即可
在这里插入图片描述

二、在QT UI界面中使用VTK窗口进行渲染

2.1 使用pushButton控制VTK窗口的显示

在widget.ui 中拖入左侧的PushButton;
在这里插入图片描述
点击PushButton右键选择转到槽 ,选择clicked() ,即点击之后显示画面;
然后widget.h中便会出现槽函数的函数声明;

private slots:
    void on_pushButton_clicked();

widget.cpp 中生成槽函数的定义;

void Widget::on_pushButton_clicked()
{

}

继续沿用一中的代码:
其中:
widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <QWidget>
#include <vtkSmartPointer.h>
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include <vtkNew.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    vtkSmartPointer<vtkRenderer> renderer;//这个渲染器其实也可以放在OnOpenSlot()中
    void OnOpenSlot();//负责生成模型和添加渲染窗口画面
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "./ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    renderer = vtkSmartPointer<vtkRenderer>::New();//在构造函数中进行初始化
}

Widget::~Widget()
{
    delete ui;
}

void Widget::OnOpenSlot()
{
    vtkSmartPointer<vtkConeSource> cone=vtkSmartPointer<vtkConeSource>::New();//生成一个圆锥,用于展示
    cone->SetHeight(3.0);
    cone->SetRadius(1);
    cone->SetResolution(10);

    vtkSmartPointer<vtkPolyDataMapper> coneMapper=vtkSmartPointer<vtkPolyDataMapper>::New();
    coneMapper->SetInputConnection(cone->GetOutputPort());
    vtkSmartPointer<vtkActor> coneActor=vtkSmartPointer<vtkActor>::New();
    coneActor->SetMapper(coneMapper);
    renderer->AddActor(coneActor);
    vtkNew<vtkGenericOpenGLRenderWindow> renwindow;
    renwindow->AddRenderer(renderer);
    renwindow->Render();
    ui->qvtkWidget->SetRenderWindow(renwindow.Get());
    ui->qvtkWidget->update();
}

void Widget::on_pushButton_clicked()
{
    qDebug()<<"Show Renderer Windows!!\n";
    OnOpenSlot();
}

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    qDebug()<<"RUN MAIN";
    return a.exec();
}

2.2 运行

点击左下角的运行;
在这里插入图片描述
点击PushButton, VTK控件窗口中显示模型渲染画面;
在这里插入图片描述

2.3 不使用PushButton

OnOpenSlot() 函数直接放在Widget的构造函数中,在QT界面初始化之后就可以显示VTK的模型渲染界面;

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值