使用Qt CPP编写动态库和QML组件并应用在其它工程里,这里提供一个简易的方案,可能会有一些问题,比如QtCreator提示爆红,没有找到模块等等。这里我的API的目录如下
CoreAPI // 工程目录
CPP/qmldir // 只存放注册模型和QML注册组件
debug/lib 存放dll和lib文件
Include/ 存放头文件
lib 存放lib dll文件
Src 存放源文件
*.pro *.pri pro当前工程文件和测试用到的文件
QT += gui quick
TEMPLATE = lib
DEFINES += LDAPI_LIBRARY
INCLUDEPATH += \
$$PWD/include
DLL_NAME = LDAPI
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_JOIN = _
VERSION_SUFFIX = d
CONFIG(debug, debug|release): {
message(OUT_DLL: $$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR$$VERSION_SUFFIX)
TARGET = $$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR$$VERSION_SUFFIX
DESTDIR = $$PWD/debug/lib
}
else: {
message(OUT_DLL: $$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR)
TARGET = $$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR
DESTDIR = $$PWD/lib
}
SOURCES += \
Src/DemoCpp.cpp \
Src/Util/LdUtil.cpp
DISTFILES += \
Demo.pri \
QML/MyRect.qml
HEADERS += \
Include/DemoCpp.h \
Include/LdExport.h \
Include/Util/LdUtil.h // Demo.pro
这里使用TARGET和DESTDIR来生成DLL lib位置。
在Demo.pri里在导入相应的DLL lib需要注意不用添加DEFINES,需要使用INCLUDEPATH的$$PWD 否则找不到这里,因为该目录和测试用到的目录可能比较远。
小TIPS: 有时为了避免复制dll到测试工程目录里,可以添加LIBS+= xx/bin 也就是把dll的目录也添加上就可以了,这里导出的dll lib在同一目录里就不需要了。
QT += gui
QT += quick
QT += websockets
QT += gui-private
QT += webengine
QT += concurrent
HEADERS += \
$$PWD/*.h \
$$PWD/include/*.h \
$$PWD/include/Util/*.h
INCLUDEPATH +=\
$$PWD/include \
$$PWD
DLL_NAME = LDAPI
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_JOIN = _
VERSION_SUFFIX = d
CONFIG(debug, debug|release):LIBS += -L$$PWD/debug/lib -l$$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR$$VERSION_SUFFIX
else: LIBS += -L$$PWD/lib -l$$DLL_NAME$$VERSION_JOIN$$VERSION_MAJOR$$VERSION_JOIN$$VERSION_MINOR
// Demo.pri
Include和Src里添加导出模型 Util目录添加cpp里类,这里省略部分代码。需要注意,使用单例模式的资源清除有时需要处理,不会调用析构函数。
#include "DemoCpp.h"
#include "Util/LdUtil.h"
#include <QQmlEngine>
ld::DemoCpp::~DemoCpp()
{
}
void ld::DemoCpp::registerModules(QString uri)
{
qmlRegisterType<ld::LdCPP>(uri.toStdString().c_str(), 1, 0, "LdCPP");
}
void ld::DemoCpp::registerEngineModules(QQmlApplicationEngine *engine)
{
...
}
// DemoCpp.cpp
QML/MyRect.qml 添加代码
import QtQuick 2.0
import CPP 1.0
Item {
LdCPP{
}
} //MyRect.qml
在注册的CPP模块下 添加 qmldir 指定QML的位置和模块名,有时会有一些依赖关系,这里略。
module CPP
MyRect 1.0 ../QML/MyRect.qml
// CPP/qmldir
当注册其它模块名时需要修改目录CPP名和module CPP,有时也要修改到MyRect.qml的相对位置。
在测试工程pro文件里导入 include(.../Demo.pri) 添加QML_IMPORT_PATH = xxx../CoreAPI
在main.cpp里添加
#include "DemoCpp.h"
ld::DemoCpp API;
API.registerModules("CPP");
QQmlApplicationEngine engine;
engine.addImportPath("..../CoreAPI"); // 之前CoreAPI的目录
这样就可以在main.qml里调用MyRect.qml了
import QtQuick 2.12
import QtQuick.Window 2.12
import CPP 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MyRect{
Component.onCompleted: {
console.log("dddd")
}
}
}
这里如果有爆红或者没有找到CPP 1.0 等提示问题, 需要重新编译CoreAPI 或者重启IDE,运行后结果如下