VTK随笔十三:QT与VTK的交互

news2024/12/26 11:59:08

一、基于 Ot的 VTK 应用程序

        以 VTK 读入一幅 JPG 图像,然后在 Qt 界面上使用 VTK 显示该图像为例,演示QT与VTK的交互。

1、创建QT项目QT_VTK_Demo

 

2、配置VTK库

 在CMakeLists.txt中添加如下代码:

 

 配置完成后重新打开工程加载VTK库。

3、编写代码

在mainwindow.ui中添加一个OpenGL Widget,提升为QVTKOpenGLNativeWidget ,头文件QVTKOpenGLNativeWidget.h

添加一个打开文件的菜单

mainwindow.h 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <vtkEventQtSlotConnect.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_action_triggered(); //响应打开图像文件的槽函数
    void updateCoords(vtkObject* obj);//响应鼠标移动的消息,实时输出鼠标的当前位置

private:
    Ui::MainWindow *ui;

    vtkEventQtSlotConnect* m_Connections;
    vtkSmartPointer<vtkImageViewer2>  m_pImageViewer;
    vtkSmartPointer<vtkRenderer>  m_pRenderder;
};
#endif // MAINWINDOW_H

 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QFileDialog>
#include <vtkRenderWindow.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkEventQtSlotConnect.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_pImageViewer  = vtkSmartPointer< vtkImageViewer2 >::New();
    m_pRenderder = vtkSmartPointer< vtkRenderer >::New();
    m_pRenderder->SetBackground(1.0,1.0,1.0);

    // 设置m_QVTKWidget的渲染器
    ui->renWin->renderWindow()->AddRenderer(m_pRenderder);

    m_Connections = vtkEventQtSlotConnect::New();
    m_Connections->Connect(ui->renWin->renderWindow()->GetInteractor(), vtkCommand::MouseMoveEvent,this,SLOT(updateCoords(vtkObject*)));
}

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

void MainWindow::on_action_triggered()
{
    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;

    // 用vtkJPEGReader读取JPG图像
    vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
    reader->SetFileName(fileName.toUtf8().data());
    reader->Update();

    // 将reader的输出作为m_pImageViewer的输入,并设置m_pImageViewer与渲染器m_pRenderer的关联
    m_pImageViewer->SetInputData(reader->GetOutput());
    m_pImageViewer->UpdateDisplayExtent();
    m_pImageViewer->SetRenderWindow(ui->renWin->renderWindow());
    m_pImageViewer->SetRenderer(m_pRenderder);
    m_pImageViewer->SetupInteractor(ui->renWin->renderWindow()->GetInteractor());
    m_pImageViewer->SetSliceOrientationToXY(); //默认就是这个方向的
    m_pImageViewer->GetImageActor()->InterpolateOff();
    m_pRenderder->ResetCamera();
    m_pRenderder->DrawOn();
    ui->renWin->renderWindow()->Render();
}

void MainWindow::updateCoords(vtkObject* obj)
{
    // 获取交互器
    vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);

    // 获取鼠标的当前位置
    int event_pos[2];
    iren->GetEventPosition(event_pos);

    QString str = QString("x=%1 : y=%2").arg(event_pos[0]).arg(event_pos[1]);
    ui->statusbar->showMessage(str);
}

 运行效果:

        vtkEventQtSlotConnect 类可以实现 VTK 的事件与 Qt 的槽函数的连接。示例中演示了当移动鼠标时,在窗口上显示当前鼠标的像素坐标值。

        在VTK中,可以通过两种方式来实现观察者/命令模式实现交互行为,它们分别是使用事件回调函数以及从 vtkCommand 派生出具体的子类。


1) 事件回调函数

在类 vtkObject 中,有如下函数:
  unsigned long AddObserver(unsigned long event, vtkCommand*, float priority = 0.0f);
  unsigned long AddObserver(const char* event, vtkCommand*, float priority = 0.0f);
函数的作用就是针对某个事件添加观察者到某个 VTK 对象中,当该对象发生观察者感兴趣的事件时,就会自动调用回调函数,执行相关的操作。

2)vtkCommand 子类
观察者/命令模式除了使用事件回调函数外,还可以直接从vtkCommand 类中派生出子类来实现。

        vtkRenderWindowInteractor 提供了一种独立于平台的交互机制,用来响应不同平台的鼠标、按键和时钟等消息。当渲染窗口中有事件发生时,如单击消息,vkRenderWimndowInteractor内部会调用与平台相关的子类,将该消息转换成对应平台的消息。 

 

二、选择拾取 

        选择拾取是人机交互过程的一个重要功能。

1. 点拾取

        vtkPointPicker是vtkPicker的子类,它返回选择点的ID以及坐标。它也是通过发射光线与Actor相交而拾取对象的,除了返回坐标值,Actor和Mapper,它也返回在指定容差内沿着光线,最靠近光线的那个点的ID。vtkPointPicker::GetPointId()可以获取点的ID号。
  vtkPointPicker不能单一拾取,其速度比vtkPicker慢,但比vtkCellPicker要快。 

2. 单元拾取

         vtkCellPicker是vtkPicker的子类,它返回选择单元的ID以及坐标。它也是通过发射光线与Actor相交而拾取对象的,除了返回坐标值,Actor和Mapper,它也返回在指定容差内沿着光线,最靠近光线的那个单元的ID。vtkPointPicker::GetCellId()可以获取单元的ID号。vtkCellPicker可以单一拾取,其速度是所有Picker中最慢的,当然,提供的信息也是最丰富的。

3. Actor 的拾取(vtkPropPicker)

         vtkPropPicker是基于图形硬件拾取一个Actor/Prop实例,速度比vtkCellPicker/vtkPointPicker快。这个类在世界坐标系统中判定Actor/Prop和拾取位置,对于点和单元的ID则不作判定。 

	vtkSmartPointer<vtkPropPicker>			
    m_pPropPicker{ nullptr };
	m_pPropPicker = vtkSmartPointer<vtkPropPicker>::New();

//启用拾取列表,之后的拾取仅从该列表内匹配
	m_pPropPicker->SetPickFromList(true);

//添加Actor
	vtkNew<vtkActor> actor;
	vtkNew<vtkActor> actor1;
	m_pPropPicker->AddPickList(actor);
	m_pPropPicker->AddPickList(actor1);

//拾取
	if (m_pPropPicker->Pick(displayPos[0], displayPos[1], 0, DefaultRenderer) > 0)
		{
		
		//拾取结果是Assembly
			auto pPickAssembly = m_pPropPicker->GetAssembly();
		//拾取结果是Actor
			auto pPickActor = m_pPropPicker->GetActor();
		}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2106145.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制裁下的转型:俄罗斯加密货币战略布局与人民币挂钩BRICS稳定币的崛起

在国际制裁重压下&#xff0c;俄罗斯正在积极推进加密货币政策改革&#xff0c;通过设立加密货币交易所和推动与人民币挂钩的BRICS稳定币&#xff0c;试图在全球金融体系中谋求新的生存与发展路径。这一系列举措标志着俄罗斯在数字经济领域的重大转向&#xff0c;既是对当前经济…

Linux【5】远程管理

目录 shutdown关机 ifconfig输出网卡信息 ping ip地址——检测连接正常 ssh 【-p port】 userip scp不同主机之间的文件copy 当前文件复制到远程 远程文件复制到本地 复制文件夹 -r shutdown关机 shutdown -r 重启 ifconfig输出网卡信息 ping ip地址——检测连接正常…

集成电路学习:什么是PCB印刷电路板

一、PCB&#xff1a;印刷电路板 PCB&#xff0c;全称为Printed Circuit Board&#xff0c;即印刷电路板&#xff0c;是现代电子设备中不可或缺的基础构件。它作为电子元器件的载体和连接体&#xff0c;在电子设备中发挥着至关重要的作用。以下是对PCB的详细解析&#xff1a; 二…

【C++初阶】一、C++入门(万字总结)

「前言」 「专栏」C详细版专栏 &#x1f308;个人主页&#xff1a; 代码探秘者 &#x1f308;C语言专栏&#xff1a;C语言 &#x1f308;C专栏&#xff1a; C &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 目录 一、关于C 1.1 什么是C 1.2 C 发展史 二、C关键字(C…

5.8幂律变换

目录 示例代码1 运行结果1 示例代码2 运行结果2 补充示例原理 示例&#xff1a;使用cv::pow进行图像处理 代码 运行结果 ​编辑 补充 实验代码3 运行结果3​编辑 在OpenCV中&#xff0c;幂律变换&#xff08;Power Law Transformations&#xff09;是一种常用的图像…

集成电路学习:什么是MOSFET(MOS管)

一、MOSFET&#xff1a;MOS管 MOSFET&#xff0c;全称Metal-Oxide-Semiconductor Field-Effect Transistor&#xff0c;即金属-氧化物半导体场效应晶体管&#xff0c;也常被称为MOS管或金氧半场效晶体管。它是一种可以广泛使用在模拟电路与数字电路的场效应晶体管&#xff08;f…

【游戏安全】CheatEngine基础使用——如何对不同类型的数值进行搜索?如何破解数值加密找到想修改的数值?

游戏安全 不同数值类型的搜索破解简单数值加密 不同数值类型的搜索 可以在游戏中看到很精确的物品数量&#xff0c;但是在CE中却什么都扫不到。 这是因为他的数值类型可能并不是四字节的&#xff0c;在游戏中这个数值的机制是一个慢慢增长的数值&#xff0c;所以他很有可能是…

【重学 MySQL】八、MySQL 的演示使用和编码设置

【重学 MySQL】八、MySQL 的演示使用和编码设置 MySQL 的使用演示登录 MySQL查看所有数据库创建数据库使用数据库创建表插入数据查询数据删除表或数据库注意事项 MySQL 的编码设置查看 MySQL 支持的字符集和排序规则服务器级别的编码设置数据库级别的编码设置表级别的编码设置列…

Python3.8绿色便携版嵌入式版制作

Python 的绿色便携版有两种:官方 Embeddable 版本(嵌入式版);安装版制作的绿色版。Embeddable 版适用于需要将 Python 集成到其他应用程序或项目中的情况,它不包含图形界面的安装程序,只提供了 Python 解释器和必要的库文件。安装版包含了 Python 解释器、标准库和其他一些…

基于ssm+vue+uniapp的高校课堂教学管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

8. GIS数据分析师岗位职责、技术要求和常见面试题

本系列文章目录&#xff1a; 1. GIS开发工程师岗位职责、技术要求和常见面试题 2. GIS数据工程师岗位职责、技术要求和常见面试题 3. GIS后端工程师岗位职责、技术要求和常见面试题 4. GIS前端工程师岗位职责、技术要求和常见面试题 5. GIS工程师岗位职责、技术要求和常见面试…

Ferrari求解四次方程

参考&#xff1a; 1&#xff09; https://proofwiki.org/wiki/Ferrari’s_Method#google_vignette 2&#xff09;https://blog.csdn.net/qq_25777815/article/details/85206702

【精彩回顾·成都】COC 成都阿里云 CMeet:AIGC 创新应用技术实践!

文章目录 前言一、活动介绍二、精彩分享内容及活动议程2.1、《COC 成都社区情况和活动介绍》2.2、《浅谈 AIGC 商业化》2.3、《通义大模型与 AI 技术在各行业领域的实践与探索》2.4、《话题一&#xff1a;AIGC 在内容创作领域的革新》2.5、《话题二&#xff1a;AIGC 在技术与工…

【ubuntu使用笔记】nvme磁盘挂载失败问题记录

no object for d-bus interface 问题 no object for d-bus interface 解决方法 systemctl --user restart gvfs-udisks2-volume-monitor文件格式错误 问题 解决方法 sudo ntfsfix /dev/nvme4 sudo mount /dev/nvme4 soft/

828华为云征文|基于Flexus X实例云服务器的实际场景-等保三级服务器设置

&#x1f534;大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 先看这里 写在前面3️⃣mysql创建安全管理员、审计管理员✅解决方法增加安全管理员增加审计管理员账户❌问题描述✅解决方法 3️⃣linux登录失败问题❌问题描述✅解决方法 3️…

ARM N2微架构介绍

简介 之前在“ARM V2处理器微架构介绍”一文中介绍了面向服务器、云计算等应用的ARM V2处理器微架构&#xff0c;V系列具有更强性能&#xff0c;N系列强调性能和功耗等方向的平衡&#xff0c;本文就将介绍一下ARM N2处理器微架构相比较前代的一些提升。尽管ARM还具备一代N1/V1…

【论文阅读】CiteTracker: Correlating Image and Text for Visual Tracking

paper&#xff1a;NorahGreen/CiteTracker: [ICCV23] CiteTracker: Correlating Image and Text for Visual Tracking (github.com) code&#xff1a;NorahGreen/CiteTracker: [ICCV23] CiteTracker: Correlating Image and Text for Visual Tracking (github.com) 简介 现有…

我与Linux的爱恋:Linux的基本指令

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:Linux的学习 Linux的指令介绍 1.1 pwd pwd用来查看当前目录 1.2 ls指令 ls[选项][目录或文件] 对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息 -a 列出目录下的所有文件,包括以 …

对一个已经运行的LabVIEW VI进行控制

要对一个已经运行的LabVIEW VI进行控制&#xff0c;可以采用多种方法&#xff0c;这取决于你想要控制的内容以及具体的应用场景。以下是几种常见的实现方式&#xff1a; 1. 使用全局变量或功能全局变量&#xff08;FGV&#xff09; 方法: 你可以创建全局变量或功能全局变量&am…

【揭秘】AdaBoost:那些年,我们一起追过的算法

在往期文章机器学习进阶之路&#xff1a;集成学习带你走向巅峰和揭秘Bagging与随机森林&#xff1a;构建更强大预测模型的秘密中&#xff0c;我们总结了集成学习的原理&#xff0c;并展开介绍了集成学习中Bagging和随机森林这一分枝算法&#xff0c;在本篇博客中&#xff0c;我…