操作系统: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的模型渲染界面;