在上文中,我们创建了一个简单的CMakeLists.txt来管理Qt工程。这篇文章中,我们将根据上文的脚本文件写出管理Qt和VTK工程的CMakeLists.txt.
cmake_minimum_required(VERSION 3.5)
project(VTKImbuedQt 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)
find_package(Qt5 COMPONENTS Widgets REQUIRED)
# new added
find_package(VTK REQUIRED)
add_executable(cmakeProject
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
target_link_libraries(cmakeProject
PRIVATE
Qt5::Widgets
# new added
${VTK_LIBRARIES}
)
我们可以看到相比之前我们只是添加了两行代码
find_package(VTK REQUIRED)
${VTK_LIBRARIES}
其实也就是用find_package命令来找到VTK所需要的头文件,以及将VTK的动态库链接到本案例中。结合上一篇文章中的讲解,此处应该不难理解。 (如何安装Qwt并将其集成到QtCreator/designer中?_jemnde的博客-CSDN博客)
我们将比对Qwt和VTKChartXY的画图比较,我们将左侧添加一个QFrame,其内部放置VTK的一个openGL控件(QVTKOpenGLNativeWidget);右侧放置一个QWtPlot的控件(通过Qt Designer拖入,具体操作步骤请参考如何安装Qwt并将其集成到QtCreator/designer中?_jemnde的博客-CSDN博客)。如下图所示。
下面代码将给出如何将VTK显示窗口添加到界面中。我们首先创建一个QVTKOpenGLNativeWidget,然后我们将为其设置一个render window,再为此render window添加一个渲染器。
auto VTKOpenGLWidget = new QVTKOpenGLNativeWidget(this);
VTKOpenGLWidget->setMinimumSize(50, 100);
QLayout* layout = new QGridLayout();
layout->addWidget(VTKOpenGLWidget);
ui->frame->setLayout(layout);
// setup scene window
vtkNew<vtkGenericOpenGLRenderWindow> window;
VTKOpenGLWidget->setRenderWindow(window.Get());
auto renderer = vtkSmartPointer<vtkRenderer>::New();
VTKOpenGLWidget->renderWindow()->AddRenderer(renderer);
因为我们也引用了Qwt的控件,所以我们需要将Qwt的目录以及动态库在cmake里面显示声明一下。因为对于Qt和VTK我们使用了find_package()命令,其可以自动找到头文件的路径,因此不需要include_directories. If you want to link with a library without including the source of the library in a sub directory of your project, then you use find_package
.
cmake_minimum_required(VERSION 3.5)
project(VTKImbuedQt 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)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(VTK REQUIRED)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(
"/usr/local/qwt-6.2.0/include")
set(PROJECT_SRCS mainwindow.cpp)
set(PROJECT_HEADERS mainwindow.h)
set(PROJECT_UIS mainwindow.ui)
add_executable(cmakeProject
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
target_link_libraries(cmakeProject PRIVATE
Qt5::Widgets
${VTK_LIBRARIES}
"/usr/local/qwt-6.2.0/lib/libqwt.so"
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS cmakeProject
MODULES ${VTK_LIBRARIES}
)
下面我们来看一下最终结果
参考:
张晓东 罗火灵 《VTK图形图像开发进阶》
VTK官方例子
备注:Difference between (target_)link_libraries and (target_)include_directories
*include_directories
is used to supply a list of include directories to the compiler. When a file is included using the pre-processor, these directories will be searched for the file.
*link_libraries
is used to supply a list of libraries (object archives) to the linker. If the linked item is a cmake target, with specified include directories, they don't need to be specified separately with*include_directories
.The
target_*
versions apply only to the target that is given as an operand. The non-target versions apply to all targets in the directory. Thetarget_*
versions should be used whenever possible (i.e. pretty much always).
find_package
is used to search for cmake settings from external sources i.e. outside of the project. If you want to link with a library without including the source of the library in a sub directory of your project, then you usefind_package
. From a lower level point of view,find_package(Foo)
looks for a cmake moduleFindFoo.cmake
and executes the module. The purpose of the module is to generate cmake variables or targets that can be used to include the corresponding dependency.
add_library
is similar toadd_executable
, except it adds a target for a library, rather rather than an executable. Library targets can be used as items inlink_libraries
, and their dependencies are transitive by default.