利用Qt自制可import的QML插件

此内容为原创,转载请注明出处。

环境
Qt 5.12.7
window 10

Qt的插件种类很多,但有些插件的协议是GPL协议,例如QtCharts。如果项目中使用了这种插件的话,那么就必须要共享源码。
商业软件肯定是不能共享源码的,所以就只能自制插件了。
自制插件的方式有很多种,可以直接写qml文件,使用时导入qml文件就行。但如果插件的代码除了bug需要修改,那么所有使用这个qml文件的源码都需要修改,很不方便。
所以,就决定写一个可以import的插件,方便好用。也可以把插件共享出来给广大网友,而不用担心源码泄露。

这篇博客的源码,会在最尾处给出来。

第一步 新建一个扩展插件项目

扩展插件项目,新建项目>>Library>>Qt Quick 2 Extension Plugin。
新建插件项目
我们新建一个名为 QMLPlugin 的项目。
新建项目名为QMLPlugin
接下来需要输入class-name和URI,我们把URI更改成MyPlugin,class-name先不要改,等跑通整个程序后再做调整。
更改URI
然后一直点击下一步,直到完成,这个时候我们就能得到一个完整的插件扩展项目。
完整的插件扩展项目
请注意,这里有一个叫做 qmldir 的文件,打开文件看看。
在这里插入图片描述
很简单的两句话,这个文件第二步有用。

第二步 构建插件扩展项目

插件扩展项目新建完成后,我们对项目进行构建,分别用debug和release进行构建。
这样就能够得到一个debug的QMLPlugind.dll文件,和release的QMLPlugin.dll文件。注意:如果是linux的话,应该是so文件。
在这里插入图片描述
在这里插入图片描述
我们在桌面新建一个文件夹 MyPlugin(当然也可以叫其他名字),把我们刚刚构建出来的QMLPlugind.dll和QMLPlugin.dll,还有第一步的qmldir文件,放入到MyPlugin文件夹中。
在这里插入图片描述
再将MyPlugin这个文件夹放到Qt安装目录的qml文件夹下面,一定要找准位置。这个文件夹下面还有许多其它的qml插件,比如说QtCharts等。
在这里插入图片描述

第三步 新建一个qml项目做测试

在第一步和第二步都做完的情况下,讲道理qml中就已经可以调用了,我们测试一下。
新建一个qml的qt项目。
在这里插入图片描述
新建完成后,我们什么都不要改,直接打开main.qml文件,import刚刚我们新做的插件。
还记得刚刚的qmldir文件吗,里面有两行代码。

module MyPlugin
plugin QMLPlugin

这个module 里面的MyPlugin就是我们要导入的对象。我们先导入试用,然后我再说为什么可以导入。
在这里插入图片描述
导入成功,程序没有报红也没有报错。
好,还记得我们新建插件扩展项目时,说先不要改动的class-name吗,那个就是可以在qml中调用的插件名 MyItem,试用一下看看。
在这里插入图片描述
还有智能提示,这说明我们成功了,写完整了看看。
在这里插入图片描述
不出意外,没有报错,编译运行也都是正常的。

第四步 讲解为什么可以导入

在第三步我们试用时已经成功了,那为什么可以做到呢。
打开我们之前新建的插件扩展项目QMLPlugin,里面有一个文件qmlplugin_plugin.cpp,打开它。
在这里插入图片描述
看到了吗,有这么一句代码:

qmlRegisterType<MyItem>(uri, 1, 0, "MyItem");

这个uri就是之前新建项目输入的URI,也是写入qmldir文件的module,也就是我们可以import导入的原因,版本为1.0。
代码最后的参数"MyItem",就是我们在qml中使用的插件名,也可以换个其它任何你喜欢的名字,但最好是要首字母大写。

第五步 创建一个自己的插件

在第四步讲了为什么可以使qml导入后,大家或许也猜到了,只要用qmlRegisterType注册一下其它的对象,那么qml不就可以调用了吗。
我们实验一下,假设我想自定义一个提示板,可以设置颜色、文字、背景等功能。
首先新建一个c++类,名为NoticeBoard。
在这里插入图片描述
因为是给qml调用,所以这个类需要继承QQuickItem,又因为需要用到画板Painter,所以继承QQuickPaintedItem类,记得勾选Add Q_OBJECT的选项,因为可能会用到信号。
在这里插入图片描述
新建类后,因为没有头函数,所以文件会报错,我们把.h和.cpp文件都补充完整。
注意:
记得要加上这一句话:Q_DISABLE_COPY(NoticeBoard),否则qml中会报红色。
因为是继承了QQuickPaintedItem类,所以一定要记得重写paint函数,否则编译会报错的。

#ifndef NOTICEBOARD_H
#define NOTICEBOARD_H

#include <QQuickPaintedItem>

class NoticeBoard : public QQuickPaintedItem
{
    Q_OBJECT
    Q_DISABLE_COPY(NoticeBoard)
public:
    NoticeBoard(QQuickItem *parent = nullptr);
    ~NoticeBoard() override;

protected:
    void paint(QPainter *painter) override;
};

#endif // NOTICEBOARD_H
#include "noticeboard.h"

NoticeBoard::NoticeBoard(QQuickItem *parent) : QQuickPaintedItem(parent)
{

}

NoticeBoard::~NoticeBoard()
{

}

void NoticeBoard::paint(QPainter *painter)
{

}

构建一下,没有报错了。如果还有再报错的话,建议把构建出来的文件全部删除后,重新构建。
修改一下qmlplugin_plugin.cpp,使得qml中能够调用到这个插件。

#include "qmlplugin_plugin.h"
#include "myitem.h"
#include "noticeboard.h"
#include <qqml.h>

void QMLPluginPlugin::registerTypes(const char *uri)
{
    // @uri MyPlugin
    qmlRegisterType<MyItem>(uri, 1, 0, "MyItem");
    qmlRegisterType<NoticeBoard>(uri, 1, 0, "NoticeBoard");
}

再使用debug和release分别对项目进行构建,将构建出来的两个dll库放入qt安装目录下,我们在第二步做的MyPlugin文件夹下。
记得一定是qt安装目录下的MyPlugin文件夹,这一步后面就不再重复了,每当更改了这个插件的代码时,都需要将dll文件更新一下。

我们去测试项目中测试一下
在这里插入图片描述
完全是没有问题的,运行也是没有问题。

第五步 让自己创建的插件有可修改属性

第四步创建插件提示板成功了,但是这个提示板没有颜色也没有文字,一片空白,现在来修改一下,首先修改颜色,我们希望在qml中可以控制提示板的颜色color属性。
我们就在NoticeBoard中增加一个color属性,用Q_PROPERTY的功能使得qml可以使用。
我们修改一下noticeboard.h和noticeboard.cpp文件。

#ifndef NOTICEBOARD_H
#define NOTICEBOARD_H

#include <QQuickPaintedItem>
#include <QPainter>

class NoticeBoard : public QQuickPaintedItem
{
    Q_OBJECT
    Q_DISABLE_COPY(NoticeBoard)
    Q_PROPERTY(QString color READ getColor WRITE setColor NOTIFY colorChanged)
public:
    NoticeBoard(QQuickItem *parent = nullptr);
    ~NoticeBoard() override;
    QString getColor() const;
    void setColor(const QString &color);

protected:
    void paint(QPainter *painter) override;

private:
    QString color = "#FF0000";

signals:
    void colorChanged();
};

#endif // NOTICEBOARD_H

#include "noticeboard.h"

NoticeBoard::NoticeBoard(QQuickItem *parent) : QQuickPaintedItem(parent)
{
}

NoticeBoard::~NoticeBoard()
{
}

QString NoticeBoard::getColor() const
{
    return color;
}

void NoticeBoard::setColor(const QString &color)
{
    this->color = color;
    emit colorChanged();
}

void NoticeBoard::paint(QPainter *painter)
{
    QBrush brush;   //画刷。填充几何图形的调色板,由颜色和填充风格组成
    brush.setColor(QColor(color));
    brush.setStyle(Qt::SolidPattern);
    QPen pen;       //画笔。
    pen.setColor(QColor(color));

    //在画板上画一个跟画板同宽同高的矩形
    painter->setPen(pen);
    painter->setBrush(brush);
    painter->drawRect(0, 0, this->width(), this->height());
}

我们去测试一下
因为我在.h文件中默认color为#FF0000红色,所以如果我不在qml中设置颜色的话,画板应该是默认红色的,运行一下看看。
在这里插入图片描述
确实是红色, 那么我们修改一下颜色值看看代码成功没有,给它一个淡黄绿。
在这里插入图片描述

是不是成功啦。那我们按照同样的方式,设置一下文字和文字的颜色。
在这里插入图片描述
棒不棒?还能给文字设置大小,粗体等等。

源码

https://github.com/MaoShengYu/QMLPlugin.git

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值