前言
之前的文档,只记录了使用qml源码的Quick模块,有时很多功能无法在qml中满足,或需要对代码进行保密时,需要在C++中实现qml控件,并发布到插件库中,本次记录下qml扩展插件相关,供需要的小伙伴参考
笔者本次使用的是win10系统
一、创建插件工程
笔者使用的是QtCreator7.0.2,可以在向导中,直接创建qml扩展插件工程
工程的名称和存放位置,随便找一个
但要注意,不要出现中文、空格、特殊字符
向导模板中,会直接将一个类注册到qml中,笔者没有修改名称
导入的uri也可以修改成自己的,笔者也没有修改,直接采用默认的
注:uri是qml中,import的模块名,若是存在于多个目录中,需要使用"."分隔
笔者为测试,选择了有代表性的Qt5.15.2和Qt6.3.0
创建工程后,会生成6个文件,可以根据需要修改
二、添加一个qml控件
笔者为省事,直接就在MyItem类上修改了。
MyItem类默认继承自QQuickItem,若需要自定义可见控件,可以从QQuickPaintedItem类派生,并重新实现paint()函数。笔者为测试,添加两个属性name、color和一个信号chartCleared、一个调用函数clearChart()
笔者的头文件修改如下
//#include <QQuickItem>
#include <QtQuick/QQuickPaintedItem>
#include <QColor>
class MyItem : public QQuickPaintedItem
{
Q_OBJECT
Q_DISABLE_COPY(MyItem)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
explicit MyItem(QQuickItem *parent = nullptr);
~MyItem() override;
QString name() const;
void setName(const QString &name);
QColor color() const;
void setColor(const QColor &color);
//实现自定义绘制
void paint(QPainter *painter) override;
Q_INVOKABLE void clearChart();
signals:
void chartCleared();
private:
QString m_name;
QColor m_color;
};
自定义绘制的paint()函数、clearChart()函数实现如下
void MyItem::paint(QPainter *painter)
{
QPen pen(m_color, 2);
painter->setPen(pen);
painter->setRenderHints(QPainter::Antialiasing, true);
painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16);
}
void MyItem::clearChart()
{
setColor(QColor(Qt::transparent));
update();
emit chartCleared();
}
若是有需要,可以再手动添加多个类,并注册到qml中。 但要注意修改以下两个位置:
1.QmlplugintestPlugin::registerTypes()中注册新的类
2.qmldir添加新的导出类型
代码比较好理解,直接仿照原来的修改就可以了
三、打包生成的插件
测试代码比较简单,直接编译就可以
在编译输出的当前目录,可以找到qmldir文件
在编译输出目录,可以找到dll文件
注:笔者截图的是debug模式下的目录,若是 release模式或profile模式,请切换到对应目录下
将这两个文件复制到特定目录下,这个目录的要求如下
1.尽量放到一个单独的目录中,若目录内有其他文件,可能会无法正常引用模块
2.目录的结构与模块名有关,如本次模块名为com.mycompany.qmlcomponents,对应的目录结构为/com/mycompany/qmlcomponents,笔者的目录如下
整个目录都放置在qmlplugin中,调用插件时,需要指定此目录
四、创建demo工程
创建一个QtQuick工程,并修改main.cpp,添加qml的导入路径,笔者添加如下,请读者按需修改
QQmlApplicationEngine engine;
engine.addImportPath(app.applicationDirPath() + "/../qmlplugin");
添加完成后,就可以在qml中使用了
五、引用插件
因为是测试程序,笔者就只简单在main.qml中测试下,代码修改如下
import QtQuick 2.15
import QtQuick.Window 2.15
import com.mycompany.qmlcomponents 1.0
Window {
id: window
width: 640
height: 480
visible: true
title: qsTr("Hello World")
MyItem {
width: window.width
height: window.height
}
}
代码很简单,首先import模块,模块的名就是之前qmldir中定义的模块名,然后就可以直接使用 MyItem类型了
直接运行程序,就可以看到如下:
说明引用插件里的类型成功了
笔者使用的源码下载
后记
Qt官方文档中,引用插件会消耗较多资源,不建议在一个模块中,引用多个插件,这个笔者未测试
有小伙伴问,可否同时引用qml文档中的类型,答案是肯定的,下篇文档中,笔者简单记录下