日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于VTK的Qt应用程序开发

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于VTK的Qt应用程序开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

分類: VTK應用示例 6622人閱讀 評論(25) 收藏 舉報 VTKQtCMake

目錄(?)[+]

VTK附帶的程序示例中大多是基于控制臺的,作為可視化開發工具包,VTK也可以與很多流行的GUI開發工具整合,比如MFC、Qt(題外話:Qt已經被Digia從諾基亞手中收購了,Qt現在的鏈接是: http://qt-project.org/,也有已經編譯好的版本: http://code.google.com/p/qt-msvc-installer/downloads/list直接下載安裝。可能因為大學課程里會教授MFC的內容,一些非計算機專業的會偏向于采用MFC,個人覺得,對于非計算機專業而言,如果一定要選擇一種GUI工具做開發的話,建議用Qt,容易上手,學習周期短)、FLTK( http://www.fltk.org/,FLTK也是跨平臺的,是一種比較輕便的GUI工具,VTK官方發布版本沒有提供對FLTK的接口,但可以借助類 vtkFlRenderWindowInteractor,來實現VTK與FLTK的整合)等等,VTK的源碼目錄里(VTK-5.10\Examples\GUI)包含有VTK與Qt、MFC、Tcl等工具的整合。考慮到VTK對Qt的特殊照顧(VTK提供了很多針對Qt的類可以非常方便地與Qt整合),以及Qt自身的一些性質(如易用性、跨平臺等),我們參考了VTK自帶的一些例子,給出了VTK與Qt整合的詳細步驟。

1.???CMakeLists.txt文件

我們已經知道了VTK工程的管理是用CMake的,而Qt自身有qmake工具,如果對于一些小工程而言,單純的Qt程序用qmake來構建工程,確實很方便,但如果隨著工程復雜度的增加以及工程依賴其他的函數庫時,使用CMake來管理工程或許是一個明智的選擇。而且隨著你對CMake語法的了解,你會發現用CMake來管理工程是一件非常棒的事情。

我們先看看對于單純的Qt工程,怎么來寫CMakeLists.txt腳本文件。

1.1 用CMake來管理Qt工程

官方對于這個話題給出的解釋在這里。我們引用一下這篇博文的圖,然后給出每句CMakeLists.txt腳本的注釋,結合這個圖以及腳本的注釋,相信你應該能明白了。

?

[plain] view plaincopy
  • #----------------------------------------------??
  • #?下面這兩行,沒什么好解釋的??
  • cmake_minimum_required(?VERSION?2.8?)??
  • project(?YourProjectName?)??
  • ???
  • #----------------------------------------------??
  • #?下面這兩行,也沒什么好解釋的??
  • find_package(?Qt4?REQUIRED?)??
  • include(?${QT_USE_FILE}?)??
  • ???
  • #----------------------------------------------??
  • #?程序所有源文件。<TODO:在此處添加源文件>??
  • #?定義變量Project_SRCS,其值為所列的文件列表??
  • SET(?Project_SRCS??
  • ????main.cpp??
  • ??)??
  • ???
  • #----------------------------------------------??
  • #?程序所有UI文件。<TODO:在此處添加UI文件>??
  • #?定義變量Project_UIS,其值為所列的文件列表??
  • SET(?Project_UIS??
  • ????YourQtWindows.ui??
  • )??
  • ???
  • #----------------------------------------------??
  • #?所有包含Q_OBJECT的頭文件。<TODO:在此處添加頭文件>??
  • #?定義變量Project_MOC_HDRS,其值為所列的文件列表??
  • SET(?Project_MOC_HDRS??
  • ????YourQtProjectFiles.h??
  • )??
  • ???
  • #-----------------------------------------------??
  • #?通過Qt的uic.exe生成UI文件對應的ui_XXXX.h文件??
  • #?將生成的ui_XXXX.h文件放在變量Project_UIS_H里,??
  • #?QT4_WRAP_UI就是干這個事情。??
  • QT4_WRAP_UI(?Project_UIS_H?${Project_UIS}?)??
  • ???
  • #-----------------------------------------------??
  • #?通過Qt的moc.exe生成包含Q_OBJECT的頭文件對應的??
  • #?moc_XXXX.cxx文件,將生成的moc_XXXX.cxx文件放在??
  • #?變量Project_MOC_SRCS里。QT4_WRAP_CPP就是干這個事情。??
  • QT4_WRAP_CPP(?Project_MOC_SRCS?${Project_MOC_HDRS}?)??
  • ???
  • #-----------------------------------------------??
  • #?Qt的MOC和UIC程序生成的moc_XXXX.cxx和ui_XXXX.h??
  • #?等文件是存放在CMake的“Where?to?build?the?binaries"??
  • #?里指定的目錄里,所以必須都這些路徑包含進來。??
  • INCLUDE_DIRECTORIES(?${Project_SOURCE_DIR}??
  • ?????????????????????${CMAKE_CURRENT_BINARY_DIR}??
  • ???????????????????)??
  • ???
  • #-----------------------------------------------????????????????????????????
  • #?Qt程序如果有資源文件(*.qrc),要包含資源文件,??
  • #?然后用Qt的rcc.exe生成相應的qrc_XXXX.cpp文件。??
  • #?QT4_ADD_RESOURCES就是干這個事情。??
  • SET(?Project_RCCS?YourProject.qrc)??
  • QT4_ADD_RESOURCES(?Project_RCC_SRCS?${Project_RCCS})??
  • ???
  • #-----------------------------------------------??
  • #?根據程序的cpp文件、頭文件以及中間生成的ui_XXXX.h、??
  • #?moc_XXXX.cxx、qrc_XXXX.cxx等生成可執行文件,并鏈接??
  • #?Qt的動態庫(Qt的動態庫都定義在QT_LIBRARIES變量里了)??
  • ADD_EXECUTABLE(?YourProjectName??
  • ????????????????${Project_SRCS}??
  • ????????????????${Project_UIS_H}??
  • ????????????????${Project_MOC_SRCS}??
  • ????????????????${Project_RCC_SRCS}?????????????????????????????
  • ??????????????)??
  • TARGET_LINK_LIBRARIES?(?YourProjectName?${QT_LIBRARIES}?)??
  • 1.2 用CMake來管理Qt與VTK工程

    我們在上面的基礎上添加VTK相關的CMake腳本文件,如下:

    [plain] view plaincopy
  • #----------------------------------------------------------------------------------??
  • cmake_minimum_required(?VERSION?2.8?)??
  • project(?CombineQtAndVTK?)??
  • ???
  • #----------------------------------------------------------------------------------??
  • find_package(?VTK?REQUIRED?)??
  • find_package(?Qt4?REQUIRED?)??
  • ???
  • include(?${VTK_USE_FILE}?)??
  • include(?${QT_USE_FILE}?)??
  • ???
  • #----------------------------------------------------------------------------------??
  • SET(?PROJECT_SRCS??
  • ????main.cpp??
  • ????ProjectMainWindow.cpp??
  • ????)??
  • ???
  • SET(?PROJECT_UIS??
  • ????ProjectMainWindow.ui??
  • )??
  • ???
  • SET(?PROJECT_MOC_HDRS??
  • ??ProjectMainWindow.h??
  • )??
  • ???
  • #----------------------------------------------------------------------------------??
  • QT4_WRAP_UI(?PROJECT_UIS_H??
  • ?????????????${PROJECT_UIS}??
  • ???????????)??
  • ???
  • QT4_WRAP_CPP(?PROJECT_MOC_SRCS??
  • ??????????????${PROJECT_MOC_HDRS}??
  • ????????????)??
  • ???
  • #----------------------------------------------------------------------------------??
  • INCLUDE_DIRECTORIES(?${PROJECT_SOURCE_DIR}??
  • ?????????????????????${CMAKE_CURRENT_BINARY_DIR}??
  • ?????????????????????${VTK_DIR}??
  • ???????????????????)??
  • ???
  • ADD_EXECUTABLE(?CombineQtAndVTK??
  • ????????????????${PROJECT_SRCS}??
  • ????????????????${PROJECT_UIS_H}??
  • ????????????????${PROJECT_MOC_SRCS}??
  • ??????????????)??
  • ???
  • TARGET_LINK_LIBRARIES?(?CombineQtAndVTK??
  • ??${VTK_LIBRARIES}??
  • ??QVTK??
  • ??)??
  • 以上的腳本除了紅色字體標注的跟1.1注釋的不太像之外,其他的都一樣,不再解釋。

    1.3 CMake腳本里增加工程環境變量的加載

    很多非計算機專業的用戶在使用VTK進行編程時,經常會碰到類似下圖所示的一些錯誤。

    ?

    碰到這樣的錯誤以后,可能很多用戶就不知道怎么處理了,其實上面的提示信息已經寫得非常清楚了,就是缺少“vtkCommon.dll”文件。但是又有人會說:我的電腦里明明有這個文件存在啊,為什么會找不到呢?

    一般的解決方法可能是:

    方法一:將缺少的dll文件全部拷貝的工程的Debug或者Release目錄下(拷貝的時候要注意你編譯的VTK是Debug版本的還是Release版本的,如果拷錯的話,又會出現其他不可預知的錯誤了)。但是這個方法是你每建一個工程,運行工程之前得把缺少的動態庫文件又要拷貝過去,如果你不嫌麻煩的話,可以采用。

    方法二:將缺少的dll文件全部拷貝到Windows系統的目錄下,即C:\Windows\system32或者C:\Windows\system目錄下,這個方法是你拷貝一次,以后再基于你拷貝的VTK動態庫的工程運行的時候問題都解決了。但它同樣有一個問題,假如你電腦里的VTK升級成別的版本,重新編譯了一份動態庫,或者是同時在你電腦里編譯了好幾個版本的VTK,這個時候就有點凌亂了。

    為什么這兩種方法都可以解決問題?原來動態編譯的程序在啟動的時候,會搜索程序所在的目錄以及系統環境變量PATH所列的目錄,如果這些目錄有該程序需要的動態庫時,就加載它們,如果沒有,就提示無法加載相應動態庫的錯誤。

    可以在工程的CMakeLists.txt文件里添加一些腳本,把系統的PATH環境變量作一些更改,在工程啟動之前加載這些環境變量。也就是(在工程的CMakeLists.txt最后添加):

    [plain] view plaincopy
  • #-----------------------------------------------------------------------------------??
  • #?Construct?a?list?of?paths?containing?runtime?directories?for?project?applications?on?Windows??
  • set(PROJECT_RUNTIME_PATH??"${VTK_LIBRARY_DIRS}/@VS_BUILD_TYPE@;??
  • ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/@VS_BUILD_TYPE@"??
  • ????)??
  • if(QT4_FOUND)??
  • ??set(PROJECT_RUNTIME_PATH?"${PROJECT_RUNTIME_PATH};${QT_LIBRARY_DIR}/../bin")??
  • endif()??
  • ???
  • include(CreateWindowsBatchScript.cmake)??
  • ???
  • #?If?we?are?under?Windows,?create?two?batch?files?which?correctly??
  • #?set?up?the?environment?for?the?application?and?for?Visual?Studio??
  • if(WIN32)??
  • ??set(VS_SOLUTION_FILE?"${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln")??
  • ??foreach(VS_BUILD_TYPE?debug?release)??
  • ????CreateWindowsBatchScript("${CMAKE_SOURCE_DIR}/StartVS.bat.in"??
  • ??????${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat??
  • ??????${VS_BUILD_TYPE})??
  • ??endforeach()??
  • endif(WIN32)??


  • 以上的腳本也不是特別復雜,但提到了兩個文件:CreateWindowsBatchScript.cmake以及StartVS.bat.in。這兩個文件的內容分別是:

    CreateWindowsBatchScript.cmake:

    ?

    [plain] view plaincopy
  • function(CreateWindowsBatchScript?in?out?build_type)??
  • ??if(VTK_DIR)??
  • ????set(VTK_BIN_DIR?"${VTK_DIR}/bin/${build_type}")??
  • ??else()??
  • ????set(VTK_BIN_DIR)??
  • ??endif()??
  • ???
  • ??set(VS_BUILD_TYPE?${build_type})??
  • ??configure_file(${in}?${out}?@ONLY)??
  • ??#?substitute?again??
  • ??configure_file(${out}?${out}?@ONLY)??
  • endfunction()??

  • StartVS.bat.in

    ?

    [plain] view plaincopy
  • @set?CL=/D_CRT_SECURE_NO_DEPRECATE?/D_CRT_NONSTDC_NO_DEPRECATE??
  • @set?LINK=/LARGEADDRESSAWARE??
  • ???
  • PATH=@PROJECT_RUNTIME_PATH@;%PATH%??
  • "@VS_SOLUTION_FILE@"??

  • 將工程通過CMake的configure->generate以后,即可生成StartVS_debug.bat和StartVS_release.bat兩個腳本文件。如果你要編譯、運行Debug版本的工程,即雙擊StartVS_debug.bat文件打開對應的工程,同理,Release版本的也一樣。一旦按這種方式打開相應的工程,就不用再擔心類似“無法加載***.dll文件”的錯誤了。如果你的程序還增加了ITK等函數庫,也可以照著上面的腳本作相應的修改。

    注意:使用時將CreateWindowsBatchScript.cmakeStartVS.bat.in兩個文件與工程的CMakeLists.txt放在同一級目錄里。即類似下圖的目錄結構:

    ?

    2.???用QVTKWidget整合Qt&VTK

    Qt與VTK的整合可以使用VTK提供的類QVTKWidget,看這個類名就知道這個類其實就是一個Qt里的Widget (QVTKWidget派生自QWidget),所以可以把它當作普通的Qt里的Widget來使用,甚至可以在Qt Designer里像Qt的其他標準控件一樣拖來拖去。

    2.1 在Qt Designer里集成

    要實現QVTKWidget在Qt Designer里像Qt的其他標準控件一樣拖來拖去,需要把編譯生成的QVTKWidgetPlugin.dll/QVTKWidgetPlugin.lib(Release版本)復制到Qt的安裝目錄里的plugins\designer目錄下。完了以后,你會在Qt Designer里面看到如下的控件:

    ?

    2.2 讀入一幅圖像,并在Qt界面上顯示

    接下來,我們來完成一個小功能,就是讀入一幅JPG圖像,然后在Qt界面上,用VTK來顯示。功能非常簡單,程序也非常簡單。上代碼:

    ProjectMainWindow.h:

    [cpp] view plaincopy
  • #ifndef?Project_MainWindow_H??
  • #define?Project_MainWindow_H??
  • ???
  • #include?<QMainWindow>??
  • #include?"ui_ProjectMainWindow.h"??
  • ???
  • #include?<vtkSmartPointer.h>??
  • ???
  • class?vtkImageViewer2;??
  • class?vtkRenderer;??
  • ???
  • ???
  • class?ProjectMainWindow?:?public?QMainWindow,?public?Ui::ProjectMainWindow??
  • {??
  • ???????Q_OBJECT??
  • ???
  • public:??
  • ???????ProjectMainWindow();??
  • ???????~ProjectMainWindow();??
  • ???
  • private?slots:??
  • ???????//響應打開圖像文件的槽函數??
  • ???????void?onOpenSlot();??
  • ???
  • private:??
  • ???????vtkSmartPointer<?vtkImageViewer2?>?m_pImageViewer;??
  • ???????vtkSmartPointer<?vtkRenderer?>?m_pRenderder;??
  • };??
  • ???
  • #endif??

  • ProjectMainWindow.cpp:

    [cpp] view plaincopy
  • #include?"ProjectMainWindow.h"??
  • ???
  • #include?<QFileDialog>??
  • #include?<QDir>??
  • ???
  • #include?<vtkRenderWindow.h>??
  • #include?<vtkRenderer.h>??
  • #include?<vtkImageViewer2.h>??
  • #include?<QVTKWidget.h>??
  • #include?<vtkJPEGReader.h>??
  • #include?<vtkImageActor.h>??
  • ???
  • ProjectMainWindow::ProjectMainWindow()??
  • {??
  • ???????setupUi(this);??
  • ???
  • ???????m_pImageViewer??=?vtkSmartPointer<?vtkImageViewer2?>::New();??
  • ???????m_pRenderder??????=?vtkSmartPointer<?vtkRenderer?>::New();??
  • ???
  • ???????//?設置m_QVTKWidget的渲染器??
  • ???????m_QVTKWidget->GetRenderWindow()->AddRenderer(m_pRenderder);??
  • ???
  • ???????//連接打開的信號與相應的槽??
  • ???????connect(?m_OpenAction,?SIGNAL(?triggered()?),?this,?SLOT(?onOpenSlot()?)?);??
  • }??
  • ???
  • ProjectMainWindow::~ProjectMainWindow()??
  • {??
  • }??
  • ???
  • void?ProjectMainWindow::onOpenSlot()??
  • {??
  • ???????QString?filter;??
  • ???????filter?=?"JPEG?image?file?(*.jpg?*.jpeg)";??
  • ???
  • ???????QDir?dir;??
  • ???????QString?fileName?=?QFileDialog::getOpenFileName(?this,???
  • ?????????????????????????????????QString(tr("打開圖像")),?dir.absolutePath()?,?filter?);??
  • ???????if?(?fileName.isEmpty()?==?true?)?return;??
  • ???
  • ???????//?支持帶中文路徑的讀取??
  • ???????QByteArray?ba?=?fileName.toLocal8Bit();??
  • ???????const?char?*fileName_str?=?ba.data();??
  • ???
  • ???????//?用vtkJPEGReader讀取JPG圖像??
  • ???????vtkSmartPointer<vtkJPEGReader>?reader?=?vtkSmartPointer<vtkJPEGReader>::New();??
  • ???????reader->SetFileName(fileName_str);??
  • ???
  • ???????//?將reader的輸出作為m_pImageViewer的輸入,并設置m_pImageViewer與渲染器m_pRenderer的關聯??
  • ???????m_pImageViewer->SetInput(reader->GetOutput());??
  • ???????m_pImageViewer->UpdateDisplayExtent();??
  • ???????m_pImageViewer->SetRenderWindow(m_QVTKWidget->GetRenderWindow());??
  • ???????m_pImageViewer->SetRenderer(m_pRenderder);??
  • ???????m_pImageViewer->SetupInteractor(m_QVTKWidget->GetRenderWindow()->GetInteractor());??
  • ???????m_pImageViewer->SetSliceOrientationToXY();?//默認就是這個方向的??
  • ???????m_pImageViewer->GetImageActor()->InterpolateOff();??
  • ???????m_pRenderder->ResetCamera();??
  • ???????m_pRenderder->DrawOn();??
  • ???????m_QVTKWidget->GetRenderWindow()->Render();??
  • }??

  • 程序運行結果:

    ?

    2.3 用vtkEventQtSlotConnect實現VTK事件與Qt槽的連接

    類vtkEventQtSlotConnect可以實現VTK的事件與Qt的槽函數的連接,VTK的事件主要在vtkCommand.h文件里定義,包括鼠標單擊、鼠標雙擊、鼠標移動等等,如:

    vtkCommand::ProgressEvent

    vtkCommand::ErrorEvent

    vtkCommand::WarningEvent

    vtkCommand::PickEvent

    vtkCommand::StartPickEvent

    vtkCommand::EndPickEvent

    vtkCommand::CharEvent

    vtkCommand::KeyPressEvent

    vtkCommand::KeyReleaseEvent

    vtkCommand::LeftButtonPressEvent

    vtkCommand::LeftButtonReleaseEvent

    vtkCommand::MouseMoveEvent

    ……

    具體的代碼實現:

    [cpp] view plaincopy
  • private?slots:??
  • ???????//響應鼠標移動的消息,實時輸出鼠標的當前位置??
  • ???????void?updateCoords(vtkObject*?obj);??
  • ???
  • private:??
  • ???????vtkEventQtSlotConnect*?m_Connections;??


  • 源文件:

    [cpp] view plaincopy
  • //構造函數里:??
  • ???????m_Connections?=?vtkEventQtSlotConnect::New();??
  • ???????m_Connections->Connect(m_QVTKWidget->GetRenderWindow()->GetInteractor(),??
  • ??????????????vtkCommand::MouseMoveEvent,??
  • ??????????????this,??
  • ??????????????SLOT(updateCoords(vtkObject*)));??
  • ???
  • //槽函數的實現??
  • void?ProjectMainWindow::updateCoords(vtkObject*?obj)??
  • {??
  • ???????//?獲取交互器??
  • ???????vtkRenderWindowInteractor*?iren?=?vtkRenderWindowInteractor::SafeDownCast(obj);??
  • ???
  • ???????//?獲取鼠標的當前位置??
  • ???????int?event_pos[2];??
  • ???????iren->GetEventPosition(event_pos);??
  • ???
  • ???????QString?str;??
  • ???????str.sprintf("x=%d?:?y=%d",?event_pos[0],?event_pos[1]);??
  • ???????m_StatusBar->showMessage(str);??
  • }??

  • 程序運行結果:

    ?

    示例代碼及該博文文檔下載地址:http://download.csdn.net/detail/www_doling_net/5137375


    ==========歡迎轉載,轉載時請保留該聲明信息==========

    版權歸@東靈工作室所有,更多信息請訪問東靈工作室


    教程系列導航:http://blog.csdn.net/www_doling_net/article/details/8763686

    ================================================

    總結

    以上是生活随笔為你收集整理的基于VTK的Qt应用程序开发的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。