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.5

import VTKOBJ 9.2
import VTK 9.2

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    onWidthChanged: { console.log(width) }

    //---------------------------------------
    //ref动态绑定 由于iValue定义了通知动作;
    //一个改变 会通知另一个改变
    property string sstring: VtkObj.sString

    Text {
        id: txt
        text: sstring
    }

    Button {
        objectName: "myButton"
        width:100
        height:100
        y:100
        onClicked: {
            VtkObj.addMsg("ee")
            VtkObj.changeVtkItem( )
            console.log ( VtkObj.sString)
            console.log (txt.text)
            console.log (sstring)
        }
    }
    //---------------------------------------

    VTKRenderWindow{
        id: vtkRenWindow
        z: 10

        //注意这个objectName, 等会要用到!!!!! x1
        objectName: "vtkRenWin"

        width: parent.width * 0.9
        height: width
        anchors.centerIn: parent
    }

    VTKRenderItem{
        id: vtkRenItem
        z: 10

        //注意这个objectName, 等会要用到!!!!! x2
        objectName: "vtkRenItem"

        anchors.fill: vtkRenWindow
        renderWindow: vtkRenWindow
        focus: true
    }

}

效果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

脆皮之“指针和数组的关系”

文章目录 1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 hello&#xff0c;大家好呀&#xff0c;窝是脆皮炸鸡。这一期是关于数组和指针的&#xff0c;我觉得并不是很难&#xff0c;但是我觉着下一期可能…

最新版Ceph( Reef版本)块存储简单对接k8s

当前ceph 你的ceph集群上执行 1.创建名为k8s-rbd 的存储池 ceph osd pool create k8s-rbd 64 642.初始化 rbd pool init k8s-rbd3 创建k8s访问块设备的认证用户 ceph auth get-or-create client.kubernetes mon profile rbd osd profile rbd poolk8s-rbd部署 ceph-rbd-csi c…

如何用 OceanBase做业务开发——【DBA从入门到实践】第六期

当应用一款新的数据库时&#xff0c;除了基础的安装部署步骤&#xff0c;掌握其应用开发方法才是实现数据库价值的关键。为此&#xff0c;我们特别安排了5月15日&#xff08;周三&#xff09;的《DBA 从入门到实践》第六期课程——本次课程将带大家了解OceanBase数据库的开发流…

学习Java的日子 Day45 HTML常用的标签

Day45 HTML 1.掌握常用的标签 1.1 标题标签 h1-h6 <h1>一级标签</h1> <h2>二级标签</h2> <h3>三级标签</h3> <h4>四级标签</h4> <h5>五级标签</h5> <h6>六级标签</h6> 显示特点&#xff1a; * 文字…

论文解读--------FedMut: Generalized Federated Learning via Stochastic Mutation

动机 Many previous works observed that the well-generalized solutions are located in flat areas rather than sharp areas of the loss landscapes. 通常&#xff0c;由于每个本地模型的任务是相同的&#xff0c;因此每个客户端的损失情况仍然相似。直观上&#xff0c;…

鸿蒙内核源码分析(文件句柄篇) | 你为什么叫句柄

句柄 | handle int open(const char* pathname,int flags); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); int close(int fd);只要写过应用程序代码操作过文件不会陌生这几个函数,文件操作的几个关键步骤嘛,跟把大…

react18【实战】tab切换,纯前端列表排序(含 lodash 和 classnames 的安装和使用)

技术要点 动态样式 className{tabItem ${currentType item.value && "active"}}安装 lodash npm i --save lodash使用 lodash 对对象数组排序&#xff08;不会改变源数组&#xff09; _.orderBy(dataList, "readNum", "desc")src\De…

WireShark对tcp通信数据的抓包

一、抓包准备工作 安装wireshark sudo apt update sudo apt install wireshark 运行 二、WireShark工具面板分析 上图中所显示的信息从上到下分布在 3 个面板中&#xff0c;每个面板包含的信息含义如下&#xff1a; Packet List 面板&#xff1a;显示 Wireshark 捕获到的所…

【项目实战】使用Github pages、Hexo如何10分钟内快速生成个人博客网站

文章目录 一.准备工作1.安装git2.安装node安装 cnpm 3.使用 GitHub 创建仓库&#xff0c;并配置 GitHub Pages0.Github Pages是什么1. 在 GitHub 上创建一个新仓库2. 创建您的静态网站3. 启用 GitHub Pages4. 等待构建完成5. 访问您的网站 二. Hexo1.什么是Hexo2.安装Hexo1. 安…

【核武器】2024 年美国核武器-20240507

2024年5月7日,《原子科学家公报》发布了最新版的2024美国核武器手册 Hans M. Kristensen, Matt Korda, Eliana Johns, and Mackenzie Knight, United States nuclear weapons, 2024, Bulletin of the Atomic Scientists, 80:3, 182-208, DOI: https://doi.org/10.1080/00963…

Vue面试经验2

Vue 你说你在vue项目中实现了自定义指令&#xff0c;如何实现 全局指令在main.js入口文件中实现 使用方法&#xff1a;v-指令名称 每个钩子函数都有两个参数&#xff08;ele,obj&#xff09; ele:绑定指令的元素 obj:指令的一些信息&#xff08;比如绑定指令的值&#xff0c…

OpenCV中的模块:点云配准

点云配准是点云相关的经典应用之一。配准的目的是估计两个点云之间位姿关系从而完成两者对应点之间的对齐/对应,因而在英文中又叫“align”、“correspondence”。笔者曾经是基于OpenCV进行三维重建的,并且从事过基于深度学习的6DoF位置估计等工作。在这些工作中,除了重建点…

docker compose kafka集群部署

kafka集群部署 目录 部署zookeeper准备工作2、部署kafka准备工作3、编辑docker-compose.yml文件4、启动服务5、测试kafka6、web监控管理 部署zookeeper准备工作 mkdir data/zookeeper-{1,2,3}/{data,datalog,logs,conf} -p cat >data/zookeeper-1/conf/zoo.cfg<<EOF…

基于STM32F401RET6智能锁项目(使用库函数点灯、按键)

点灯硬件原理图 1、首先&#xff0c;我们查看一下原理图&#xff0c;找到相对应的GPIO口 LED_R低电平导通&#xff0c;LED4亮&#xff0c;所以LED_R的GPIO口需要配置一个低电平才能亮&#xff1b; LED_G低电平导通&#xff0c;LED3亮&#xff0c;所以LED_R的GPIO口需要配置一…

[C++核心编程-06]----C++类和对象之对象模型和this指针

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

VTK 数据类型:规则网格

VTK 数据类型&#xff1a;规则网格 VTK 数据类型&#xff1a;规则网格分类三种规则网格需要的设置实例 VTK 数据类型&#xff1a;规则网格 分类 VTK 有 3 种规则网格&#xff1a; vtkImageData&#xff1a;几何结构和拓扑结构都是规则的。vtkRectilinearGrid&#xff1a;几何…

使用2G内存求20亿个数字中出现次数最多的N个

又是一个TOP -N的题目 我看了一下CSDN上大多数人的回答和GPT说的差不多&#xff0c;都是说使用哈希之类的&#xff1b; 我今天说一下我的解法&#xff0c;首先说一下不太快的基础解法 20亿数字使用uint32需要80GB&#xff0c; &#xff08;1&#xff09;分为40块读取&#…

云粒智慧实时数仓的架构演进分享:OceanBase + Flink CDC

4月20日&#xff0c;在2024 OceanBase开发者大会上&#xff0c;云粒智慧的高级技术专家付大伟&#xff0c;分享了云粒智慧实时数仓的构建历程。他讲述了如何在传统数仓技术框架下的相关努力后&#xff0c;选择了OceanBase Flink CDC架构的实时数仓演进历程。 业务背景及挑战 …

【C#进阶】简单数据结构类

简单数据结构类 文章目录 1、Arraylist1、ArrayList的本质2、声明3、增删查改4、装箱拆箱思考 背包售卖 2、Stack1、Stack的本质2、声明3、增取查改4、遍历思考 计算一个数的二进制 3、Queue1、Queue的本质2、声明3、增取查改4、遍历思考 每隔一段时间打印一条消息 4、Hashtab…

赣红孵联合卫东街道未保站开展未成年人保护法散落在每个角落活动

为进一步提高家长的法治意识&#xff0c;依法保障未成年人的合法权益&#xff0c;全力构建安全和谐文明家庭&#xff0c;5月8日&#xff0c;赣红孵社会组织培育中心联合卫东街道未成年人保护站在在南师附小红谷滩校区实验小学开展“未成年人保护法散落在每个角落”未成年人普法…