目录
项目场景
开发的时候,我们往往是分工协作的
每个人负责不同的开发模块
qt提供了支持qml扩展模块开发
为我们的团队开发更加的便利
比如说
一个人负责权限管理的开发
一个人负责数据库模块的开发
一个人负责通讯协议的开发
一个人负责市场业务接口的开发
一个人负责应用组件库开发
那很好我们只需要封装成一个个qml扩展模块
然后集成到一个qml应用程序中既可
你不需要关心模块里面的实现,你只需要使用负责模块工程师提供的接口直接使用即可
因为目前qt 市面上组件库的开发已经很流行了,
为此我就对组件库开发做一个教学
使用qt5.15进行
qmake工程项目
项目内容
创建扩展模块子目录项目

创建qml扩展插件库子工程
工程名MyMouleUI
为什么不写成mymodule-ui, qtcreator不允许,所以还是采用驼峰法命名


确定qt版本,这里url就是qt引入模块名

直接完成我们就会得到一个这样的结构

修改工程文件生成plugins.qmltypes
qml扩展插件需要提供plugins.qmltypes解释说明qml插件
以方便qtcreator工具能识别高亮显示智能补全
cpp
#自动生成plugins.qmltypes
CONFIG += qmltypes
QML_IMPORT_NAME = MyModuleUI
QML_IMPORT_MAJOR_VERSION = 1
QML_IMPORT_MINOR_VERSION = 0

新增qml组件
为MyModuleUI新增qml文件存放目录qml,新增文件MyButton.qml

在qmldir 中暴露MyButton.qml

编译安装qml插件库
创建全局配置MyModule.pri
qmake子项目工程不像cmake能父工程能向子工程变量
因此在MyModule.pro写的定义变量在子工程MyModuleUI是用不了的
我们需要通过引入(MyModule.pri)进行加载管理
cpp
MYMODULE_INSTALL_PREFIX = E:/qml #path/install
#MyModuleUI配置
DEFINES += MYMODULEUI_INSTALL
MYMODULEUI_INSTALL_PREFIX = $$MYMODULE_INSTALL_PREFIX
修改MyModuleUI.pro工程文件配置
cpp
#引入全局配置
include(../MyModule.pri)
#安装配置
if(contains(DEFINES,MYMODULEUI_INSTALL)){
MYMODULEUI_INSTALL_LIB = $$MYMODULEUI_INSTALL_PREFIX/$$replace(uri, \., /)
qmldir.files = qmldir
qmldir.path = $$MYMODULEUI_INSTALL_LIB
qmltypes.files = $$OUT_PWD/plugins.qmltypes
qmltypes.path = $$MYMODULEUI_INSTALL_LIB
qmlfiles.files = qml/*.qml
qmlfiles.path = $$MYMODULEUI_INSTALL_LIB/qml
target.path = $$MYMODULEUI_INSTALL_LIB
INSTALLS += target qmldir qmlfiles qmltypes
}
新增make 参数install ,make时候执行安装

(path/install )代表安装目录
我的安装目录E:/qml (一般你应该放到你产品项目的目录中才对)

创建测试子项目
子项目名字MyModuleTest

测试项目引入扩展库
修改工程文件 以便于qtcreator工具查找扩展模块
cpp
QML_IMPORT_PATH = path/install

修改main.cpp
cpp
engine.addImportPath("path/install");

main.qml使用

创建动态链接库MyModuleCore
我们的组件库会有样式管理
我们往往可能需要到qml中立马就会渲染样式,
如果这个时候希望加载的不是默认样式,启动的时候就会触发二次渲染
我们希望渲染前就准备好要渲染的样式,启动只渲染一次
这个时候我们就考虑在qml引擎加载之前,先设置一下组件库的样式配置
我们就需要提供一个中间配置库给到组件库端跟使用端
也就是MyMuduleCore
新增样式管理器
MyStyleManager

cpp
#ifndef MYSTYLEMANAGER_H
#define MYSTYLEMANAGER_H
#include "MyModuleCore_global.h"
#include <QObject>
#include <QColor>
class MYMODULECORE_EXPORT MyStyleManager : public QObject
{
Q_OBJECT
Q_PROPERTY(QColor colorBg READ colorBg WRITE setColorBg NOTIFY colorBgChanged FINAL)
public:
static MyStyleManager* getInstance();
QColor colorBg() const;
void setColorBg(const QColor &colorBg);
signals:
void colorBgChanged();
private:
explicit MyStyleManager(QObject *parent = nullptr);
static MyStyleManager* m_instance;
QColor m_colorBg;
};
#endif // MYSTYLEMANAGER_H
#include "mystylemanager.h"
MyStyleManager* MyStyleManager::m_instance = nullptr;
MyStyleManager::MyStyleManager(QObject *parent)
: QObject{parent}
{
m_colorBg = QColor(255,255,255);
}
MyStyleManager *MyStyleManager::getInstance()
{
if(m_instance == nullptr)
{
m_instance = new MyStyleManager;
}
return m_instance;
}
QColor MyStyleManager::colorBg() const
{
return m_colorBg;
}
void MyStyleManager::setColorBg(const QColor &colorBg)
{
if(m_colorBg != colorBg)
{
m_colorBg = colorBg;
emit colorBgChanged();
}
}
增加全局配置

cpp
#MyModuleCore配置
DEFINES += MYMODULECORE_INSTALL
MYMODULECORE_INSTALL_PREFIX = $$MYMODULE_INSTALL_PREFIX
MyModuleCore增加安装配置
cpp
include(../MyModule.pri)
#安装配置
# Default rules for deployment.
if(contains(DEFINES,MYMODULECORE_INSTALL)){
MYMODULECORE_INSTALL_LIB = $$MYMODULECORE_INSTALL_PREFIX/MyModuleCore
includefiles.files = MyModuleCore_global.h \
mystylemanager.h
includefiles.path = $$MYMODULECORE_INSTALL_LIB/include
target.path = $$MYMODULECORE_INSTALL_LIB
INSTALLS += target includefiles
}
MyModuleCore编译安装

新增引入配置MyModuleCore.pri
cpp
QT += gui
INCLUDEPATH += $$PWD/include
HEADERS += \
$$PWD/include/mystylemanager.h \
$$PWD/include/MyModuleCore_global.h
LIBS += -L$$PWD -lMyModuleCore
修改MyModuleCore工程文件
cpp
#安装配置
# Default rules for deployment.
if(contains(DEFINES,MYMODULECORE_INSTALL)){
MYMODULECORE_INSTALL_LIB = $$MYMODULECORE_INSTALL_PREFIX/MyModuleCore
includefiles.files = MyModuleCore_global.h \
mystylemanager.h
includefiles.path = $$MYMODULECORE_INSTALL_LIB/include
prifile.files = MyModuleCore.pri
prifile.path = $$MYMODULECORE_INSTALL_LIB
target.path = $$MYMODULECORE_INSTALL_LIB
INSTALLS += target includefiles prifile
}
MyModuleUI使用MyModuleCore
工程文件修改
cpp
include(E:/qml/MyModuleCore/MyModuleCore.pri)
修改扩展库的注册
cpp
qmlRegisterType<MyItem>(uri, 1, 0, "MyItem");
qmlRegisterSingletonType<MyStyleManager>(uri,1, 0,"MyStyleManager",
[](QQmlEngine* engine, QJSEngine* scriptEngine)->QObject* {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return MyStyleManager::getInstance();
});

MyButton.qml修改
重新执行编译安装
cpp
import QtQuick 2.15
import QtQuick.Templates 2.15 as T
import MyModuleUI 1.0
T.Button {
id: control
implicitWidth: implicitContentWidth + leftPadding +rightPadding
implicitHeight: implicitContentHeight + topPadding +bottomPadding
padding: 6
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
color: MyStyleManager.color
}
}
MyModuleTest引入MyModuleCore
修改工程文件
cpp
include(E:/qml/MyModuleCore/MyModuleCore.pri)
main.cpp修改
在渲染前设置配置

渲染后调用



问题总结
- 扩展插件每次新增,使用新增组件没高亮,但是运行正常
因为qtcreator工具得触发重新扫描,选择重置代码模型
或者重新打开项目

2.为什么不用qmlRegisterSingletonInstance注册单例配置
很奇怪就是这个不会高亮提示但是能正常运行
我们还是使用qmlRegisterSingletonType比较好