Qt QML的插件(Qt Quick 2 Extension Plugin)方法

Qt Quick的插件方法

  • 序言
  • 环境
  • 前置注意
  • 概念——Qt Quick插件的相关知识
    • 插件里的qml文件
    • 模块名的相关知识
      • 模块名本身注意事项
      • 模块名版本注意事项
  • 以示例来说明
    • 创建插件
      • qmltypes的生成
        • qmltypes的可能性失效
    • 插件的编码注意
      • 1、插件模块版本控制
      • 2、pro里的注意
    • 调用插件
      • 插件信息输入

序言

网上有很多的Qt Quick扩展插件方法,比如龚建波或者诺谦的,确实是教了怎么做,可是还是按着做时还是出现了一些问题,有些细节上的理解容易与作者想的不一样,对于新手不太友好,不够简单和全面,起码我看着没有第一时间弄出来,还花了不少时间研究才最终弄出来。

因此我作为更新手的视角也来写一下插件的用法,以供学习的人分别参考。

如果有兴趣,我后面也可以出C++的插件方法,不过感觉资料很多没什么必要。

环境

Qt5.15(MSVC2019)
VS2019

前置注意

示例插件名: TestQmlPlugin
模块名:QmlEditorStyle
插件库名:TestQmlPlugin

概念——Qt Quick插件的相关知识

Qt的插件,有一个很大的特点,就是不需要lib文件,只需要dll文件,就可以进行动态装载。

如果是C++,会需要QPluginLoader进行加载,不过其实也是用的QLibrary。

QML不需要自己来加载,因为Engine已经负责了这个加载任务。

不过相对的,Qt Quick也需要一些信息,比如插件的外接接口的信息,我们提供的就是一个名为:qmldir 的文件,无.txt,.pri那些后缀,就叫qmldir
在这里插入图片描述

关于qmldir里面该怎么写,Qt的助手就已经有相关说明:

在这里插入图片描述

具体有什么可以自行翻找查阅,但是qmldir最起码需要两条信息,也是我演示用的其中两条:
在这里插入图片描述
在这里插入图片描述
一个交代了QML的import时的模块名,另一个交代了插件库的库名。
举例:
qmldir文件里只有两行信息:

module QmlEditorStyle
plugin TestQmlPlugin

而其分别影响的是:

module QmlEditorStyle
->

import QmlEditorStyle 1.0

.
plugin TestQmlPlugin
->
TestQmlPlugin.dll
TestQmlPlugind.dll
.

插件里的qml文件

有些人,会想将QML文件放进插件里,这样调用的时候就可以拿着dll随便用了。

可惜,实现不了。

插件本质上是一种特殊的动态库,动态库你我都懂,如果需要调用动态库里面的类,就需要提供一些接口.h文件。

然后编码时才可以自由访问提供的接口类。

同理,你要调用QML文件,就必须要有接口,可怎么提供接口呢?QML文件就没有分什么.h文件,.cpp文件,它是解释型语言,就算用插件,你也需要提供源码才可以。

除非你用C++实现QML的项,然后封装进插件里,再放出.h文件即可。(因为QML的项本质上是QtC++的实现而来的。)

将自己封装好的QML文件放在插件库文件夹里,即下文会提到的QmlEditorStyle文件夹里。

再将qmldir文件夹的末尾,加上资源标识符 注册的版本 对应文件
在这里插入图片描述
其对应的就是

qmlRegisterType<MySliderItem>("QmlEditorStyle", 1, 0, "Slider");

ResourceIdentifier对应的是Slider,注册的QML类型
InitialVersion对应的是1, 0,C++是1逗号0,qmldir是1点0
File对应的是MySliderItem,实际的QML文件,C++的是实际的C++类

module QmlEditorStyle
...
Slider 1.0 MySliderItem.qml

不过一般都会文件和类型名一致。

这样就算是将QML文件放进插件库里了,当调用该文件夹的插件时,也会囊括QML文件了。

模块名的相关知识

Qt Quick的import模块名,值得注意的是,其代表的其实是文件夹名,什么意思呢?
比如说QtQuick.Window 2.15这个import的模块,实际代表的是QtQuick文件夹里的Window.2文件夹
在这里插入图片描述

Creator会根据这个,从路径信息里找到对应的文件夹,找到对应的plugins.qmltypes文件和qmldir文件,进而读取进来。
在这里插入图片描述

模块名本身注意事项

有的人可能要自己定义一个插件库,比如说:[公司名].[库名]
然后就打算这样命名文件夹:Company.TestQmlPlugin

这样是行不通的,Creator会找不到插件库的,你得改成 Company文件夹里放TestQmlPlugin文件夹

模块名版本注意事项

那么如果说我们导入示例插件TestQmlPlugin呢?

比如说import TestQmlPlugin 1.0
就直接是TestQmlPlugin文件夹里放就行,后面的.1可加可不加,没有会默认按.1处理

如果是import TestQmlPlugin 2.0
就需要命名为:TestQmlPlugin.2文件夹,这个不能缺少后面的.2

.
另外还需要一个文件,plugins.qmltypes,其提供给Creator提示信息,是由我们用qmlplugindump生成的,或者qmake的里面设置一些东西可以自动生成。

基本这些加上库文件就组成了一个插件。
在这里插入图片描述

以示例来说明

创建插件

在这里插入图片描述

按选择,创建插件的这个工程名,与提供出来的插件名不影响
在这里插入图片描述
选择qmake还是cmake进行编译,Qt6只运行用cmake,如果用QML,以后考虑用Qt6的,就选择cmake。
但是呢,这里现在暂时只讲解qmake方法,cmake待后续添加。
在这里插入图片描述
接下来选择一些基本信息,如最低Qt版本这些,URI的com.mycompany.qmlcomponents,可以改为我们示例用的模块名QmlEditorStyle,或者你打算设置的模块名。
在这里插入图片描述
.
在这里插入图片描述
.
在这里插入图片描述
如此就生成了初始的插件
在这里插入图片描述
进行构建,就可以生成debug版本或者release版本这些的dll了。

不需要在意debug版本,dll名是否会因为有个d后缀而影响的问题,Qt在读取的时候会自动判断的了。

将构建好的dll和qmldir放进由模块名为文件夹名的文件夹里。
在这里插入图片描述

qmltypes的生成

在该文件夹的上一级,用cmd输入:

qmlplugindump QmlEditorStyle 1.1 . > .\QmlEditorStyle\plugins.qmltypes

其的输入规则是:
qmlplugindump+空格+[模块名]+空格+[版本]+空格+[模块所在目录]+空格+ > +空格+[要生成的路径]

需要注意的是,[模块所在目录]是指以模块名为文件夹名的文件夹所在目录,即QmlEditorStyle文件夹。
在这里插入图片描述
生成之后会在模块文件夹里即QmlEditorStyle生成一个plugins.qmltypes,是qmlplugindump根据插件里注册的内容,生成的信息。

qmltypes的可能性失效

1、生成了plugins.qmltypes可能是缺少信息的,也可能是我指令有误之类的吧,但是参考别人的也都是相同的。
在这里插入图片描述
注意上方的exports这行信息,在每个MyItem的左边,需要加上模块名QmlEditorStyle/MyItem 1.1

这样才能生效

2、如果上方加上了模块名仍然Creator提示无效,则在qmldir里新增一行:

typeinfo plugins.qmltypes

不过一般来说加不加不影响

3、如果上边的都弄了之后,发现在导入的地方存在一个错误提示
Error 1:1 预计符号numeric literal
这是编码问题,我遇到了,发现plugins.qmltypes是utf-16格式的,于是我转成了utf-8格式的就正常了
.

插件的编码注意

1、插件模块版本控制

Qt Quick的模块版本,是由注册到该版本的项决定是否存在的。

什么意思呢?

testqmlplugin_plugin.cpp里,有个代码

void TestQmlPluginPlugin::registerTypes(const char *uri)
{qmlRegisterType<MyItem>(uri, 1, 0, "MyItem");
}

uri代表的是会传入你编写的模块名,比如说该示例是QmlEditorStyle,uri也是这个值。

第二个参数是主版本号,第三个参数是次版本号。

就是import QmlEditorStyle 1.0里的1是主版本号,0是次版本号。

这样将MyItem注册在了1.0这个模块里,1.0就存在了一个MyItem的项。

你如果后面都弄好后平白无故去导入1.1模块也是不存在的,会提示不存在这个模块,因为里面不包含任何项。

2、pro里的注意

TEMPLATE = lib
TARGET = TestQmlPlugin		// 插件的dll名称
QT += qml quick
CONFIG += plugin c++11TARGET = $$qtLibraryTarget($$TARGET)
uri = QmlEditorStyle		// 代表着模块名,一般用不上

此处如果额外增加下列代码

CONFIG += qmltypes #自动生成 plugins.qmltypes
QML_IMPORT_NAME = TestQmlPlugin
QML_IMPORT_MAJOR_VERSION = 1

就会自动在构建之后产生一个plugins.qmltypes代码了,可以免掉后面再自行命令行用qmlplugindump了。

不过要自行更改QML_IMPORT_MAJOR_VERSION版本,其代表的是主版本号。

.

调用插件

接下来就是怎么去使用我们的插件了

首先,在上文生成插件后,有一个QmlEditorStyle的文件夹。

将这个文件夹放到使用的工程文件下,专门放QML插件的一个文件夹下,我这里是qml文件夹,你也可以命名为DLL或者其他什么的,名字不影响。
在这里插入图片描述

插件信息输入

有两处需要填写插件信息的:
第一处是pro里,有个QML_IMPORT_PATH,增加qml所在路径。

QML_IMPORT_PATH += C:/Project/Qt/build-testQtQML-Desktop_Qt_5_15_2_MSVC2019_32bit-Release/release/qml

我这里放的是生成的目标路径位置,也可以放工程里,是一样的,不影响。

第二处是在main.cpp里,有个engine,调用engine增加插件路径。

QQmlApplicationEngine engine;
engine.addImportPath(QString("%1/qml").arg(app.applicationDirPath()));		// 可以用绝对路径之类的,指向qml文件夹
const QUrl url(QStringLiteral("qrc:/main.qml"));
...

第三处是调用处的qml里:

import QtQuick 2.15
import QtQuick.Window 2.15
import QmlEditorStyle 1.1			// 调用对应的模块Window {width: 640height: 480visible: truetitle: qsTr("Hello World")MyItem {			// 使用默认提供的C++的Itemwidth: 100height: 100fillColor: "red"}
}

上边如果import QmlEditorStyle 1.1或者MyItem有报错,则是没有配置好。

如果能正常运行,则是plugins.qmltypes没有弄好。

以上全部都弄好后,应该是这样的:
正常显示无报错
正常显示无报错

在这里插入图片描述
item能正常显示

至此,Qt Qucik的插件方法教程结束。

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

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

相关文章

华为手机 鸿蒙系统 或者安卓系统的百度网盘下载的文件保存在手机什么位置如何查看

华为手机 鸿蒙系统 或者安卓系统的百度网盘下载的文件保存在手机什么位置如何查看 连接电脑后一般在这里位置 计算机\Mate 20 Pro (UD)\内部存储\Download\BaiduNetdisk 也就是用usb&#xff08;数据线&#xff0c;不是充电线&#xff0c;要四心的 )连接手机后&#xff0c;打…

计算机网络——40各个层次的安全性

各个层次的安全性 安全电子邮件 Alice需要发送机密的报文m给Bob Alice 产生随机的对称秘钥&#xff0c; K s K_s Ks​使用 K s K_s Ks​对报文进行加密&#xff08;为了效率&#xff09;对 K s K_s Ks​使用Bob的公钥进行加密发送 K s ( m ) K_s(m) Ks​(m)和 K B ( K S ) K…

uniapp如何配置后使用uni.chooseLocation等地图位置api

在uniapp中想要使用uni.getLocation、uni.chooseLocation ……api的时候我们需要在小程序就开启配置&#xff0c;不然无法使用。 第一步&#xff1a;首先找到manifest.json 第二步&#xff1a;点击源码视图 第三步&#xff1a;在 mp-weixin 加入下面代码 "permission&…

Paper Digest | GPT-RE:基于大语言模型针对关系抽取的上下文学习

持续分享 SPG 及 SPG LLM 双驱架构应用相关进展 1、动机 在很多自然语言处理任务中&#xff0c;上下文学习的性能已经媲美甚至超过了全资源微调的方法。但是&#xff0c;其在关系抽取任务上的性能却不尽如人意。以 GPT-3 为例&#xff0c;一些基于 GPT-3 的上下文学习抽取方…

DXP学习002-PCB编辑器的环境参数及电路板参数相关设置

目录 一&#xff0c;dxp的pcb编辑器环境 1&#xff0c;创建新的PCB设计文档 2&#xff0c;PCB编辑器界面 1&#xff09;布线工具栏 2&#xff09;公用工具栏 3&#xff09;层标签栏 ​编辑 3&#xff0c;PCB设计面板 1&#xff09;打开pcb设计面板 4&#xff0c;PCB观…

【HTML】简单制作一个分形动画

目录 前言 开始 HTML部分 效果图 ​编辑​编辑​编辑​编辑总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建一个文本文档&#xff0c;其中HTML的文件名改为[index.html]&a…

JavaEE初阶之单例模式详解

目录 题外话 正题 单例模式 概念 优点 缺点 饿汉式单例模式 代码及详解 懒汉式单例模式 代码及详解 小结 题外话 昨天爬山去了,回来吃了个烧烤有点累,昨天旷了一天,每周稳定发个五篇文章是没什么太大问题的 正题 单例模式 概念 是一种常见的软件设计模式,确保一个类…

nginx 配置访问地址和解决跨域问题(反向代理)

1、配置访问地址&#xff08;通过ip访问&#xff09; //配置ip访问地址 location ^~/auditApp{alias /usr/local/front-apps/cbd/auditApp;index index.html;if (!-e $request_filename) {rewrite ^/(.*) /auditApp/index.html last;break;}} 2、解决跨域问题&…

电商技术揭秘十四:大数据平台的选择与构建

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

如何使用Java和RabbitMQ实现延迟队列(方式二)?

前言 昨天写了一篇关于Java和RabbitMQ使用插件实现延迟队列功能的文章&#xff0c;今天来讲下另外一种方式&#xff0c;不需要RabbitMQ的插件。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 需要安装RabbitMQ的可以看下面这篇文章。 如何使用PHP和R…

AWS入门实践-在EC2上部署Wordpress网站

在AWS EC2上部署WordPress涉及到几个步骤&#xff0c;包括启动EC2实例、配置数据库、安装WordPress等。以下是详细的步骤和相应的命令脚本 第一步: 启动 EC2 实例 登录 AWS 控制台,进入 EC2 服务启动一个新的 EC2 实例,选择 Amazon Linux 2 AMI选择合适的实例类型(例如 t2.mi…

Java-接口-定义接口Filter及其实现类WordFilter

所谓&#xff1a;“纸上得来终觉浅&#xff0c;绝知此事要躬行。” 关于接口的知识&#xff0c;可以几分钟过一遍&#xff1a;Java-接口—知识&#xff08;基础&#xff09;-CSDN博客 现在就是练习time&#xff0c;先来看题&#xff1a; 定义一个接口 Filter&#xff0c;表示…

linux之shell命令

shell基础命令 浏览Linux 文件系统 Linux 系统目录结构 /bin&#xff1a; bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot&#xff1a; 这里存放的是启动 Linux 时使用的一些核心文件&#xff0c;包括一些连接文件以及镜像文件。 /dev &…

免费分享 .NET C#面试宝典

为.NET和C#开发者准备的全面指南&#xff0c;涵盖了从基础知识到高级应用的各个方面。以下是对手册内容的详细总结&#xff0c;分为多个关键点进行阐述。 1. 基础语法和数据类型 数据类型和变量&#xff1a;手册介绍了基本数据类型如int、double、bool等&#xff0c;以及如何…

微服务初始及Eureka注册中心

1&#xff0c;架构演变 单体架构&#xff1a;将所有业务功能集中在一个项目中开发&#xff0c;达成一个包部署 优点&#xff1a;架构简单&#xff0c;部署成本低 缺点&#xff1a;项目耦合度高 分布式架构&#xff1a;根据业务功能对系统进行拆分&#xff0c;每个业务作为独…

PCB学习记录-----入门基础知识

一、搭建环境 1.下载嘉立创EDA 软件下载 - 嘉立创EDA (lceda.cn) 选专业版 在线编辑&#xff1a;嘉立创EDA(专业版) - V2.1.45 (lceda.cn) 官方教程&#xff1a;立创EDA专业版-使用教程 (lceda.cn) 2.新建工程 文件-新建-项目&#xff0c;右键Board1可以重命名&#xff…

-bash: cd: /etc/hadoop: 没有那个文件或目录

解决办法&#xff1a;source /etc/profile 运行 source /etc/profile 命令会重新加载 /etc/profile 文件中的配置&#xff0c;这样做的目的是使任何更改立即生效&#xff0c;而不需要注销并重新登录用户。通常&#xff0c;/etc/profile 文件包含系统范围的全局 Shell 配置&…

asp.net网上水果销售平台 水果购物商城系统+sqlserver

网上水果销售平台 说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库 功能模块&#xff1a; asp.net网上水果销售平台 水果购物商城系统 用户功能有 网站首页 全部水果 我的订单 购物车用户…

如何将CSDN的文章以PDF文件形式保存到本地

1.F12 打开开发者工具窗口 2.console下输入命令 (function(){$("#side").remove();$("#comment_title, #comment_list, #comment_bar, #comment_form, .announce, #ad_cen, #ad_bot").remove();$(".nav_top_2011, #header, #navigator").remove…

flutter组件_AbsorbPointer

官方说明&#xff1a;A widget that absorbs pointers during hit testing. 翻译&#xff1a;一个在命中测试期间吸收指针的Widget。 作者释义&#xff1a;阻止子元素的点击事件 。 AbsorbPointer的定义 const AbsorbPointer({super.key,this.absorbing true,this.ignoringSe…