【QML】QML使用C++自定义组件,动态链接库DLL构建及使用

news2024/12/28 8:16:21

1. 方法1 (C++源码)

1.1 创建一个普通的qml工程,写入ListView测试代码

import QtQuick 2.15
import QtQuick.Window 2.15

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

    ListView{
        id:lv
        width: 100
        height: 500
        spacing: 5
        model: ListModel{
            ListElement{name: "Jack";  age: "18"}
            ListElement{name: "Tom";  age: "19"}
            ListElement{name: "Rose";  age: "20"}
        }

        delegate: Rectangle{
            id: dl
            required property int index
            required property string name
            required property string age

            height: 50
            width: 100
            color: "red"
            Text{
                text: dl.index +" "+ dl.name + " "+ dl.age
            }
        }
    }
}


在这里插入图片描述

1.2 下面我们用C++实现model部分

1.3 新建C++类

注意:C++文件不要加到*.qrc
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 新建完成后,工程中多了两个文件

testmodel.cpp
testmodel.h

在这里插入图片描述

1.5 添加虚函数

  • 选中类 -> 鼠标右键 -> 重构 -> 插入虚函数
    在这里插入图片描述
    在这里插入图片描述
    注意: 三个虚函数:
    在这里插入图片描述

1.6 testmodel.h文件中添加如下内容

#ifndef TESTMODEL_H
#define TESTMODEL_H

#include <QAbstractListModel>

class TestModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit TestModel(QObject *parent = nullptr);


    // QAbstractItemModel interface
public:
    int rowCount(const QModelIndex &parent) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    QHash<int, QByteArray> roleNames() const override;

public:
    enum RoleNames{
        NameRole = 0,
        AgeRole,
    };

    typedef struct{
        QString name;
        QString age;
    } TestData_t;

private:
    QList<TestData_t>m_data;
    QHash<int, QByteArray>m_roleNames;
};

#endif // TESTMODEL_H

1.7 在textmodel.cpp代码中实现

  • 添加实现
    在这里插入图片描述
  • 此时testmodel.cpp中的内容
#include "testmodel.h"

TestModel::TestModel(QObject *parent)
    : QAbstractListModel{parent}
{

}

int TestModel::rowCount(const QModelIndex &parent) const
{

}

QVariant TestModel::data(const QModelIndex &index, int role) const
{

}

QHash<int, QByteArray> TestModel::roleNames() const
{

}

  • 添加如下内容
#include "testmodel.h"

TestModel::TestModel(QObject *parent)
    : QAbstractListModel{parent}
{
    //初始化角色
    m_roleNames[NameRole] = "name";
    m_roleNames[AgeRole] = "age";

    // 添加数据
    TestData_t testdata;
    testdata.name = "Jack";
    testdata.age = "18";
    m_data.append(testdata);

    testdata.name = "Tom";
    testdata.age = "19";
    m_data.append(testdata);

    testdata.name = "Rose";
    testdata.age = "20";
    m_data.append(testdata);
}

int TestModel::rowCount(const QModelIndex &parent) const
{
    return m_data.count();
}

QVariant TestModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();

    if(row<0 || row>=m_data.count())
        return QVariant();

    const TestData_t & testData = m_data.at(row);
	
	//根据角色返回数据
    switch(role)
    {
    case NameRole:      return testData.name;
    case AgeRole:       return testData.age;
    }

    return QVariant();
}

QHash<int, QByteArray> TestModel::roleNames() const
{
    return m_roleNames;
}

1.8 在main.cpp中注册模块

  • 添加两行代码
#include "testmodel.h"  //添加头文件

//注册类型
qmlRegisterType<TestModel>("org.test", 1, 0, "TestModel");
  • 修改后的代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "testmodel.h"  //添加头文件


int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));

    //注册类型
    qmlRegisterType<TestModel>("org.test", 1, 0, "TestModel");

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
        &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

1.9 在qml中使用

  • 导入模块
import org.test 1.0 //导入自定义模块
  • 使用模块
model: TestModel{}  //使用自定义的模块
  • 新的代码
import QtQuick 2.15
import QtQuick.Window 2.15
import org.test 1.0 //导入自定义模块

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

    ListView{
        id:lv
        width: 100
        height: 500
        spacing: 5
        model: TestModel{}  //使用自定义的模块
//            ListModel{
//            ListElement{name: "Jack";  age: "18"}
//            ListElement{name: "Tom";  age: "19"}
//            ListElement{name: "Rose";  age: "20"}
//        }

        delegate: Rectangle{
            id: dl
            required property int index
            required property string name
            required property string age

            height: 50
            width: 100
            color: "red"
            Text{
                text: dl.index +" "+ dl.name + " "+ dl.age
            }
        }
    }
}

1. 10 运行效果(与之前的一样)

在这里插入图片描述

2. 方法2(DLL动态链接库)

2.1 生成库文件

1. 新建库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 工程目录结构
    在这里插入图片描述

2. 库代码

  • 将方法1中的testmodel.h和testmodel.cpp两个文件覆盖本项目中的同名文件

3. 构建

  • 点击构建
    在这里插入图片描述

4. 生成的库文件

  • 在debug目录下生成了TestModel.dll文件
  • 把TestModel.dll和qmldir文件拷出来备用

2.2 使用库文件

1. 新建qml工程

在这里插入图片描述

2. 添加代码

  • 把方法1中main.qml的内容复制到新工程的main.qml中
  • 修改模块导入
//import org.test 1.0 
import com.test.testmodel 1.0 //导入自定义模块

4. 添加库文件

  • 将生成的库文件复制到新工程中
    在这里插入图片描述

5. 设置环境变量

windows
  • 创建批处理文件run.bat,根据实际情况修改
set QML2_IMPORT_PATH=D:\Personal\6.MyCode\0.Test\11.Qml\14_Cpp\CppDLL\dll
start D:\Soft\Qt6\Tools\QtCreator\bin\qtcreator.exe
  • 关闭qtcreator,通过run.bat启动
  • 打开刚才的qml工程
Linux - Ubuntu
  • 创建脚本文件run,根据实际情况修改
#!/bin/sh
export QML2_IMPORT_PATH=/home/book/qt_code/CppTest/DllTest/dll/
export QT_HOME=/opt/Qt/Tools/QtCreator/bin/
$QT_HOME/qtcreator $*
  • 关闭qtcreator,通过run启动
  • 打开刚才的qml工程
Linux - 开发板(qtcreator远程部署)
  • libTestModel.soqmldir拷贝到/root/com/test/testmodel/
  • 项目 - 运行 - 环境 - 批量编辑,添加QML2_IMPORT_PATH=/root/
Linux - 开发板(板子里直接运行)
  • libTestModel.soqmldir拷贝到/root/com/test/testmodel/
  • 创建脚本文件run,根据实际情况修改
#!/bin/sh
export QML2_IMPORT_PATH=/root/
./opt/DllTest
  • 或是将com文件夹直接拷贝到DllTest相同目录下,则不用配置环境变量,直接运行DllTest就行了。

6. 运行效果

在这里插入图片描述

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

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

相关文章

使用Llama index构建多代理 RAG

检索增强生成(RAG)已成为增强大型语言模型(LLM)能力的一种强大技术。通过从知识来源中检索相关信息并将其纳入提示&#xff0c;RAG为LLM提供了有用的上下文&#xff0c;以产生基于事实的输出。 但是现有的单代理RAG系统面临着检索效率低下、高延迟和次优提示的挑战。这些问题在…

第65讲:MySQL存储过程之循环语法的核心概念与应用案例

文章目录 1.存储过程中循环的种类2.WHILE循环控制2.1.WHILE循环语法格式2.2.WHILE循环经典案例 3.REPEAT循环控制3.1.REPEAT循环语法结构3.2.REPEAT循环经典案例 4.LOOP循环控制4.1.LOOP循环语法结构4.2.LOOP循环经典案例一4.3.LOOP循环经典案例二 1.存储过程中循环的种类 在存…

git 撤销已经push到远程的提交

git 撤销已经push到远程的提交 1. 情景2. 解决方法2.1 git revert2.2 git reset 1. 情景 工作中会有很多时候提交git的时候会提交错东西&#xff0c;而且已经push到远程的话怎么办呢&#xff1f; 2. 解决方法 2.1 git revert 一种常见的方法是使用 git revert 命令来创建一…

酷开科技,让家庭更有温度!

生活中总有一些瞬间&#xff0c;会让我们感到无比温暖和幸福。一个拥抱、一句问候、一杯热茶&#xff0c;都能让我们感受到家庭的温馨和关爱。酷开科技也用自己的方式为我们带来了独属于科技的温暖&#xff0c;通过全新的体验将消费者带进一个充满惊喜的世界&#xff0c;让消费…

iPhone无法关机未必是坏了!如何修复无法关闭的iPhone

iPhone运行很慢且发热是一个比较罕见的情况&#xff0c;但如果它发生在你身上&#xff0c;下面解释了发生的原因以及你如何修复它。 iPhone无法关闭的原因 iPhone无法关闭的最可能原因是&#xff1a; 由于软件问题&#xff0c;它被冻结了。 睡眠/唤醒按钮坏了。 屏幕坏了&a…

【Redis】环境配置

环境配置 Linux版本&#xff1a; Ubuntu 22.04.2 LTS 下载redis sudo apt install redis 启动redis redis-server 输入redis-server启动redis竟然报错了&#xff0c;原因是redis已经启动&#xff0c;网上大多数的解决方案如下&#xff1a; ps -ef | grep -i redis 查询redi…

软件开发项目文档系列之六概要设计:构建可靠系统的蓝图

概要设计是软件开发项目中至关重要的阶段&#xff0c;它为整个系统提供了设计蓝图和技术方向。它的重要性在于明确项目目标、规划系统结构、确定技术选择、识别风险、以及为团队提供共同的视角&#xff0c;确保项目在后续开发阶段按计划进行。概要设计的主要内容包括项目的背景…

九州未来入选“2023边缘计算产业图谱”三大细分领域

10月26日&#xff0c;边缘计算社区正式发布《2023边缘计算产业图谱》&#xff0c;九州未来凭借深厚的技术积累、优秀的产品服务、完善的产品解决方案体系以及开源贡献&#xff0c;实力入选图谱——边缘计算平台、边缘计算开源、边缘云服务提供商三大细分领域&#xff0c;充分彰…

统信UOS1060上修改sudo权限

原文链接&#xff1a;统信UOS1060上修改sudo权限 hello&#xff0c;大家好啊&#xff0c;今天给大家带来在统信UOS桌面操作系统1060上修改管理员权限&#xff0c;使其在使用sudo的时候&#xff0c;不要输入本用户密码验证的文章&#xff0c;主要通过修改 /etc/sudoers文件实现&…

恒驰服务 | 华为云数据使能专家服务offering之大数据建设

恒驰大数据服务主要针对客户在进行智能数据迁移的过程中&#xff0c;存在业务停机、数据丢失、迁移周期紧张、运维成本高等问题&#xff0c;通过为客户提供迁移调研、方案设计、迁移实施、迁移验收等服务内容&#xff0c;支撑客户实现快速稳定上云&#xff0c;有效降低时间成本…

el-upload 组件上传/移除/报错/预览文件,预览图片、pdf 等功能

目录 页面代码样式代码页面展示 页面代码 dialog.vue <!-- 上传文件 --> <template><el-dialogtitle"上传文件":visible.sync"dialogVisible"width"60%"top"6vh":close-on-click-modal"false"close"h…

中国人民大学与加拿大女王大学金融硕士——在职读研,演绎精彩的人生

为什么在职读研呢&#xff1f;这是对即将读研人的“灵魂拷问”&#xff0c;每个人读研的原因不同&#xff0c;有人因为职业瓶颈&#xff0c;有人晋升需要&#xff0c;还有人为了完成曾经的读研梦想&#xff1b;读书深造是一种经历&#xff0c;不光是学历的加持&#xff0c;我们…

API Testing v0.0.14 新增 gRPC, tRPC 协议的支持

api-testing 本次版本发布中的内容中&#xff0c;包含了两位高校同学的 contribution&#xff0c;其中屈晗煜在GitLink编程夏令营&#xff08;GLCC&#xff09;活动期间非常给力地增加了gRPC 协议的支持。 atest 版本发布 v0.0.14 atest 是一款用 Golang 编写的、开源的接口测试…

Vue3最佳实践 第八章 ESLint 与 测试 ( Jest )

Jest 测试 Vue 组件 ​在前端项目开发过程中&#xff0c;有很多时候也会要进行测试工作。本文将重点介绍如何利用 JavaScript 测试框架 Jest 进行高效的测试。Jest 是由 FaceBook 开发的顶级测试框架之一&#xff0c;广受开发者们的欢迎和信赖。在接下来的内容中&#xff0c;我…

【Ubuntu 系统使用进入,自动进入base虚拟环境解决最全】

项目场景&#xff1a; 在Ubuntu上安装完anaconda后&#xff0c;发现每次打开终端后都会自动进入到base的虚拟环境中去&#xff0c;虽然在这些环境下使用问题不大&#xff0c;但一些软件的安装在虚拟环境下有影响。每次使用conda deactivate退出也很麻烦。 问题描述 安装玩之…

软件测试这些基本类型你知道吗

关于软件测试的类型&#xff0c;从不同角度来讲&#xff0c;可以分很多种&#xff0c;有时候甚至觉得软件测试是人类创造出来的最复杂的职业。。。 对一些常见的测试类型做了一个基本的文档总结&#xff0c;有些测试类型在之前的基础知识里面已经有所介绍&#xff0c;这里就没…

【Python爬虫+可视化】解析小破站热门视频,看看播放量为啥会这么高!评论、弹幕主要围绕什么展开

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用 Python 3.8 Pycharm 模块使用 import requests import csv import datetime import hashlib import time 一. 数据来源分析 明确需求 明确采集网站以及数…

Linux Spug自动化运维平台公网远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…

Unity HoloLens 2 应用程序发布

设置3D 启动器画面&#xff0c;glb格式的模型 VS中可以直接生成所有大小的图标