QML及VTK配合构建类MVVM模式DEMO

1 创建QT QUICK项目

这次我们不在主程中加载VTK的几何;

在qml建立的控件,创建MyVtkObject类的单例,main中将指针和单例挂钩;

在MyVtkObject实例中操作 QQuickVTKRenderItem 类即可;

由于VTK的opengl显示是状态机,所以无需进行MVVM的通知动作(类MVVM模式);

这里再次采用按钮触发修改动作;

2 构建类 MyVtkObject

myvtkobject.h
#ifndef MYVTKOBJECT_H
#define MYVTKOBJECT_H#include <QObject>#include <QQuickVTKRenderWindow.h>
#include <QQuickVTKRenderItem.h>
#include <vtkPolyDataMapper.h>
#include <vtkCylinderSource.h>
#include <vtkCubeSource.h>class MyVtkObject : public QObject
{Q_OBJECT
public:explicit MyVtkObject(QObject *parent = nullptr);Q_INVOKABLE void initVtkView();Q_INVOKABLE QString addMsg(QString str);Q_INVOKABLE QString changeVtkItem( );void setRenderItem( QQuickVTKRenderItem* _item){this->m_vRenItem=_item ;};void setRenderWin(QQuickVTKRenderWindow* _win){this->m_vRenWin=_win ;}//单例static MyVtkObject* getInstance( ){static MyVtkObject* myobj = new MyVtkObject() ;return myobj;};const QString &sString() const;void setSString(const QString &newSString);private:QString m_sString="init";QQuickVTKRenderItem* m_vRenItem;QQuickVTKRenderWindow* m_vRenWin;Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)signals:void sStringChanged();
};#endif // MYVTKOBJECT_H

myvtkobject.cpp

#include "myvtkobject.h"MyVtkObject::MyVtkObject(QObject *parent): QObject{parent}
{}void MyVtkObject::initVtkView()
{vtkNew<vtkCylinderSource> cylinder;cylinder->SetResolution(8);// The mapper is responsible for pushing the geometry into the graphics// library. It may also do color mapping, if scalars or other attributes are// defined.vtkNew<vtkPolyDataMapper> cylinderMapper;cylinderMapper->SetInputConnection(cylinder->GetOutputPort());// The actor is a grouping mechanism: besides the geometry (mapper), it// also has a property, transformation matrix, and/or texture map.// Here we set its color and rotate it around the X and Y axes.vtkSmartPointer<vtkActor> cylinderActor=vtkSmartPointer<vtkActor>::New();cylinderActor->SetMapper(cylinderMapper);//    cylinderActor->GetProperty()->SetColor( colors->GetColor4d("Tomato").GetData());cylinderActor->RotateX(30.0);cylinderActor->RotateY(-45.0);auto main_render_3d = m_vRenItem->renderer();main_render_3d->AddActor(cylinderActor);main_render_3d->ResetCamera();//    QQuickVTKRenderWindow* ren_win_3d = engine.rootObjects().first()
//            ->findChild< QQuickVTKRenderWindow* >( "vtkRenWin" );m_vRenWin->render();}QString MyVtkObject::addMsg(QString str)
{setSString(sString()+ str + '#' ) ;// m_sString = str+"@";qDebug()<< __FUNCTION__ <<" === "<<str;return sString();
}QString MyVtkObject::changeVtkItem()
{vtkNew<vtkCylinderSource> cylinder;cylinder->SetResolution(8);vtkNew<vtkPolyDataMapper> cylinderMapper;cylinderMapper->SetInputConnection(cylinder->GetOutputPort());vtkSmartPointer<vtkActor> cylinderActor=vtkSmartPointer<vtkActor>::New();cylinderActor->SetMapper(cylinderMapper);cylinderActor->RotateX(-30.0);cylinderActor->RotateY(-95.0);//    auto qquickvtkItem =m_vRenItem;  // vtkSmartPointer<QQuickVTKRenderItem> ::New()   ;auto main_render_3d = m_vRenItem->renderer();//    main_render_3d->Clear();main_render_3d->AddActor(cylinderActor);main_render_3d->ResetCamera();vtkActorCollection* actors =main_render_3d->GetActors();qDebug()<< __FUNCTION__ <<" actors count: "<< actors->GetReferenceCount();return "OK";
}const QString &MyVtkObject::sString() const
{return m_sString;
}void MyVtkObject::setSString(const QString &newSString)
{if (m_sString == newSString)return;m_sString = newSString;emit sStringChanged();
}

3 主程中连接qml中vtk控件的指针

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>#include "myvtkobject.h"int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif//定义app之前调用一次,别问我为啥,问就是官方文档上写的,我也不知道QQuickVTKRenderWindow::setupGraphicsBackend();QGuiApplication app(argc, argv);QQmlApplicationEngine engine;//=====注册给qml=======qmlRegisterSingletonInstance("VTKOBJ",9,2,"VtkObj",MyVtkObject::getInstance());qmlRegisterType<QQuickVTKRenderWindow>("VTK", 9, 2, "VTKRenderWindow");qmlRegisterType<QQuickVTKRenderItem>("VTK", 9, 2, "VTKRenderItem");//====================const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);//------------------------------------auto vtkItem = engine.rootObjects().first()->findChild< QQuickVTKRenderItem* >( "vtkRenItem" );auto vtkWin = engine.rootObjects().first()->findChild< QQuickVTKRenderWindow* >( "vtkRenWin" );MyVtkObject::getInstance()->setRenderItem(vtkItem);MyVtkObject::getInstance()->setRenderWin(vtkWin);MyVtkObject::getInstance()->initVtkView();//------------------------------------return app.exec();
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5import VTKOBJ 9.2
import VTK 9.2Window {width: 640height: 480visible: truetitle: qsTr("Hello World")onWidthChanged: { console.log(width) }//---------------------------------------//ref动态绑定 由于iValue定义了通知动作;//一个改变 会通知另一个改变property string sstring: VtkObj.sStringText {id: txttext: sstring}Button {objectName: "myButton"width:100height:100y:100onClicked: {VtkObj.addMsg("ee")VtkObj.changeVtkItem( )console.log ( VtkObj.sString)console.log (txt.text)console.log (sstring)}}//---------------------------------------VTKRenderWindow{id: vtkRenWindowz: 10//注意这个objectName, 等会要用到!!!!! x1objectName: "vtkRenWin"width: parent.width * 0.9height: widthanchors.centerIn: parent}VTKRenderItem{id: vtkRenItemz: 10//注意这个objectName, 等会要用到!!!!! x2objectName: "vtkRenItem"anchors.fill: vtkRenWindowrenderWindow: vtkRenWindowfocus: true}}

效果

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bpmn.js使用(仅查看版)

Bpmn.js使用&#xff08;仅查看版&#xff09; 下载 npm install bpmn-js创建一个 Dom 节点来挂载画布元素。 <a-tabs v-model:activeKey"activeKey" change"tabsChange"><a-tab-pane key"1" tab"审批记录"><a-tabl…

保护宝贵的历史财富——博物馆文物管理

文物是一个国家的瑰宝&#xff0c;承载着历史的记忆和文化的传承及精髓。为了保护这些珍贵的文化遗产&#xff0c;仓库管理尤为重要。仓库管理的目的是确保文物的完整性、安全性和可持续保护&#xff0c;并为研究、展览和教育提供支持。 首先&#xff0c;文物仓库管理注重文物的…

前端css中径向渐变(radial-gradient)的使用

前端css中径向渐变的使用 一、前言二、主要内容说明&#xff08;一&#xff09;、径向渐变的形状1.椭圆形渐变&#xff08;ellipse&#xff09;&#xff0c;源码12.源码1运行效果3.圆形渐变&#xff08;circle&#xff09;&#xff0c;源码24.源码2运行效果 &#xff08;二&…

Windows安装RabbitMQ教程(附安装包)

需要两个安装包 Erlang 安装包: https://download.csdn.net/download/Brevity6/89274663 (自己从官网下载也可以) RabbitMQ Windows 安装包&#xff1a; https://download.csdn.net/download/Brevity6/89274667 (自己从官网下载也可以) Erlang安装 Erlang安装傻瓜式下一…

数据结构05:树与二叉树 习题01[C++]

考研笔记整理&#xff0c;本篇作为树与二叉树的基本概念习题&#xff0c;供小伙伴们参考~&#x1f95d;&#x1f95d; 之前的博文链接在此&#xff1a;数据结构05&#xff1a;树与二叉树[C]-CSDN博客~&#x1f95d;&#x1f95d; 第1版&#xff1a;王道书的课后习题~&#x1…

DenseCLIP论文讲解

文章目录 简介方法总体框架 &#xff08;Language-Guided Dense Prediction&#xff09;上下文感知提示 &#xff08;Context-Aware Prompting&#xff09;应用实例 论文&#xff1a;DenseCLIP: Language-Guided Dense Prediction with Context-Aware Prompting 代码&#xff1…

最全软件测试面试问题和回答,适合全文背诵

求职&#xff0c;类似于打仗&#xff0c;是一场挑战自己的战斗&#xff0c;也是一场跟用人单位的博弈&#xff0c;更是一场千人过独木桥的厮杀、混战。《孙子谋攻篇》中早就说了&#xff1a;"知己知彼&#xff0c;百战不殆&#xff1b;不知彼而知己&#xff0c;一胜一负&a…

python数据分析——数据的选择和运算

数据的选择和运算 前言一、数据选择NumPy的数据选择一维数组元素提取示例 多维数组行列选择、区域选择示例 花式索引与布尔值索引布尔索引示例一示例二 花式索引示例一示例二 Pandas数据选择Series数据获取DataFrame数据获取列索引取值示例一示例二 取行方式示例loc() 方法示例…

error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public: __cdecl ......

运行程序时&#xff0c;报如上图所示错误&#xff0c;其中一条是&#xff1a; ReflectionProbe.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl osg::Object::Object(bool)" (__imp_??0ObjectosgQEAA_NZ) 报这个错误一般是因为…

10.轮转数组

文章目录 题目简介题目解答解法一&#xff1a;使用额外的数组代码&#xff1a;复杂度分析&#xff1a; 解法二&#xff1a;数组反转代码&#xff1a;复杂度分析&#xff1a; 题目链接 大家好&#xff0c;我是晓星航。今天为大家带来的是 轮转数组 相关的讲解&#xff01;&#…

Gradle基础学习(六) 认识任务Task

理解Gradle中的任务 Gradle的构建过程基于任务&#xff08;Task&#xff09;的概念&#xff0c;而每个任务都可以包含一个或多个动作&#xff08;Action&#xff09;。 任务是构建中执行的一些独立的工作单元&#xff0c;例如编译类、创建JAR、生成Javadoc或将存档发布到仓库…

达梦数据库限制用户登录IP测试

达梦数据库创建用户时可以限制登录ip和时间段。 创建测试测试用户 create user test1 identified by Test_1234 ALLOW_IP "192.168.100.101"; 限定该用户只能通过192.168.100.101地址登录数据库 连接测试 上图可见&#xff0c;192.168.100.101客户端可以连接上19…

【数据结构】 二叉树的顺序结构——堆的实现

普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储 。 一、堆的概念及结构 父节点比孩子结点大 是大堆 父节点比孩子结点小 是小堆 堆的性质 堆中某…

java学习笔记反射机制

2.关于反射的理解 Reflection&#xff08;反射)是被视为动态语言的关键&#xff0c;反射机制允许程序在执行期借助于Reflection API取得任何 类的内部信息&#xff0c;并能直接操作任意对象的内部属性及方法。 框架 反射 注解 设计模式。 3.体会反射机制的“动态性” //…

什么是限流?常见的限流算法

目录 1. 什么是限流 2. 常见限流算法 3. 固定窗口算法 4. 滑动窗口算法 5. 漏桶算法 6. 令牌桶算法 7. 限流算法选择 1. 什么是限流 限流&#xff08;Rate Limiting&#xff09;是一种应用程序或系统资源管理的策略&#xff0c;用于控制对某个服务、接口或功能的访问速…

WordPress插件:链接自动识别转为超链接

WordPress插件&#xff1a;链接自动识别转为超链接 <?phpfunction open_links_in_new_tab() {add_filter(the_content, make_clickable);function autoblank($text) {$return str_replace(<a, <a target"_blank", $text);return $return;}add_filter(th…

【Python】selenium爬虫常见用法和配置,以及常见错误和解决方法

欢迎来到《小5讲堂》 这是《Python》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言无执行文件代码报错信息错误路径手动下载自动下载 选项配置Ch…

面试笔记——类加载器

基础 类加载器&#xff1a;用于装载字节码文件(.class文件)运行时数据区&#xff1a;用于分配存储空间执行引擎&#xff1a;执行字节码文件或本地方法垃圾回收器&#xff1a;用于对JVM中的垃圾内容进行回收 类加载器 &#xff1a;JVM只会运行二进制文件&#xff0c;类加载器的…

组件目录存放问题

目录 一、思考引入 二、组件分类 三、组件分类的目的 一、思考引入 .vue文件本质无区别&#xff0c;而路由相关的组件&#xff0c;为什么要放在views目录呢&#xff1f; 二、组件分类 .vue文件分2类&#xff1a;页面组件和复用组件。注意&#xff1a;都是.vue文件&#xff…

调试记录 CPU PCIE 找不到设备,AC 耦合电容的问题

1. 问题 现象&#xff1a; 1. 国产CPU的主板&#xff0c;主板内的PCIE 设备找的到&#xff0c;但是另一块板子上连接的PCIE 设备找不到。 2. 排查问题在哪里的计划 1. 检查原理图先排除信号定义的问题&#xff0c; TXRX是否反接。 2. 示波器检查PCIE 的时钟频率是否正确。 3. …