maxiongyinghangsheng com cn DBUS New future new application
插件和服务培训 maxiongying@hangsheng. com. cn
Ø 项目整体框架简介 DBUS New future – new application architecture HMI(QML/Java. Script) Services/Modules QT QML Framework Add Task Interface API 业务数据处理模块 界面交互/效果展现模块 自动 Function Plug-ins(C++) Plug-in Base Controller HMI Data Cent er QT Basic Framework(C++) HMI 数据接口服务模块 界面交互/效果展现程序 控制指令 数据交换 HMI Data Server Multi-Task Distribution Thread Pool Management Basic Platform Framework(C++) 核心业务管理模块 数据业务处理服务程序
Ø HMI使用插件过程 一 , main. cpp加载整个app主程序的main. qml. int main(int argc, char *argv[]) { … engine. load(QUrl(QString. Literal("qrc: /main. qml"))); app. exec(); #ifdef USE_DLT // 开始注销DLT功能 end. DLT(); #endif return 0; } 二,在main. qml中申明插件,定义插件对象,创建插件对象 1,申明插件 import Qt. Quick 2. 3 import The. XPresenter 1. 0 import The. XMusic 1. 0 2,定义插件对象 Component { id: hmi. Com Hmi. Common. Ctl { } } Component { id: music. Com Music. Ctl { } } 3,创建插件对象 plugins. Creators: ({ hmi. Ctl: hmi. Com, musicctl: music. Com,
Ø HMI使用插件过程 三,在模块的page中使用插件 以多媒体音乐为例进行讲解,简单贴出对应代码,讲解过程中会展示完整代码 1,在整个app主程序的main. qml中加载每个模块的Application. qml,每个模块以自己的Application. qml为入口 ICore. Window { id: window // property string phone. Type property bool callflag: false multi. Applications { applications: ({ … usb: { url: Qt. resolved. Url('usb/Application. qml'), title: 'USB', /*cache: true*/}, … }} }} 2,在音乐服务Application. qml中申明要使用的page ICore. Virtual. Application { pages: ({ music_main: { url: Qt. resolved. Url('Main. Page. qml'), title: qs. Tr('USB'), requires: ['devctl', 'musicctl', 'videoctl', 'system'] }, … }}}
Ø HMI使用插件过程 3,在music. qml中生成对应page,以及请求对应的page要使用的插件 musicctl就是整个app的main. qml中定义的变量 tabs: ({ all: {url: Qt. resolved. Url('music_all. qml'), requires: [ 'devctl', 'musicctl', 'system']}, 4,在music_all中使用musicctl插件中的属性和槽函数 import The. XMusic 1. 0 UControls. Tab { property var songlist on. Musicctl. Changed: {songlist = Qt. binding(function(){return musicctl. songlist})} list. View. pagination. Loader. Delegate: UControls. Pagination. Loader. Delegate { function load. Page. Async(page, cb) { songlist. Tab. require. Plugins(['musicctl'], function (err, plugins) { if (!err ) { var musicctl = plugins[0]; musicctl. songlist. Changed. connect(function handler(songlist){ musicctl. songlist. Changed. disconnect(handler); cb(null, songlist) ; }); if(file. Count > 0){ musicctl. get. Song. List(page); } } }); } }
Ø 插件的编写及逻辑流程 二、 一个简单的插件 插件主要有四个文件The. XMusic. h、The. XMusic. cpp、The. XMusic_plugin. h、The. XMusic_plugin. cpp The. XMusic. h #ifndef HSPLUGINTEMPLATE_H #define HSPLUGINTEMPLATE_H #include <QJson. Array> #include <QJson. Value> #include <QJson. Object> #include "hs_plugin_base_controller. h" #define DESTINATION "Media. Service" class The. XMusic : public HSPlugin. Base. Controller { Q_OBJECT Q_DISABLE_COPY(The. XMusic) Q_PROPERTY(int play. State READ get. Play. State NOTIFY play. State. Changed) public: The. XMusic(HSPlugin. Base. Controller *parent = 0 ); ~The. XMusic(void); public: double get. Play. State(void) const; signals: void play. State. Changed(double play. State); public slots: void play(QString path);
Ø 插件的编写及逻辑流程 The. XMusic. cpp #include "The. XMusic. h“ #include "hs_hmidata_plugin_config. h“ #include <QDebug> The. XMusic: : The. XMusic(HSPlugin. Base. Controller *parent): HSPlugin. Base. Controller(parent) { HSSet. Destination(DESTINATION); QJson. Object obj; /*! Reserved args! */ HSRegister. Plugin(ID_PLUGIN_GROUP_USB_MUSIC, this, &obj); } The. XMusic: : ~The. XMusic(void) { HSDeregister. Plugin(HSGet. Plugin. ID(), this); } double The. XMusic: : get. Play. State(void) const { return HSGet. Plugin. Data("play. State"). to. Double(); } void The. XMusic: : play(QString path) { QJson. Value value = path; HSRequest. Data("play", value); }
Ø 插件的编写及逻辑流程 The. XMusic_plugin. h #ifndef HS_PLUGIN_TEMPLATE_PLUGIN_H #define HS_PLUGIN_TEMPLATE_PLUGIN_H #include <QQml. Extension. Plugin> class The. XMusic. Plugin : public QQml. Extension. Plugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org. qt-project. QQml. Extension. Interface") public: void register. Types(const char *uri); }; #endif // TEST 2_PLUGIN_H The. XMusic_plugin. cpp #include "The. XMusic_plugin. h" #include "The. XMusic. h" #include <qqml. h> void The. XMusic. Plugin: : register. Types(const char *uri) { //@uri the. Template qml. Register. Type<The. XMusic>(uri, 1, 0, "Music. Ctl"); }
Ø 插件的编写及逻辑流程 三,插件读取mode数据流程 The. XMusic: : get. Play. State(void) HSPlugin. Base. Controller: : HSGet. Plugin. Data(const QString &attr) HSHMIData. Center: : get. Attr(int plugin. ID, const QString &attr) Model. Attribute: : get. Attr(const QString &attr)
Ø 插件的编写及逻辑流程 四,插件获取数据变更的流程 void HSSocket. Recv: : run(void) 通过回调函数传出数据 static void HSDistribute(QJson. Object &object) 通过信号与槽将数据传出 HSHMIData. Center: : distribute. Data(QJson. Object *object) HSHMIData. Center: : distribute. Data. Plugin. ID(int id, …) HSHMIData. Center: : distribute. Data. To. Plugin(int plugin. ID…… HSHMIData. Center: : distribute. Data. To. HMI(QObject *plugin
Ø 插件的编写及逻辑流程 五,插件请求接口的流程 The. XMusic: : play(QString path) HSPlugin. Base. Controller: : HSRequest. Data(const QString &attr…) HSPlugin. Base. Controller: : HSRequest. Data(int plugin. ID…) HSHMIData. Center: : request. Service(const QString &dest, const…) HSSocket: : HSSocket. Add. Sender(const QString &dest…) HSSocket. Send: : run(void) Client. Socket: : socket. Send(QJson. Object &object)
Ø 服务的编写及逻辑流程 二,一个简单的服务例子 一个服务主要有这些文件: hs_audio_module_cls. h、 hs_audio_module_func. h、 hs_audio_module_cls. cpp、 hs_audio_module_func. cpp hs_audio_module_cls. h #ifndef HS_AUDIO_MODULE_CLS_H #define HS_AUDIO_MODULE_CLS_H #include "hs_service_module. h" #include "hs_audio_module_func. h" class HSAudio. Module. Cls : public HSAudio. Module. Func. Cls , public HSjson { public: HSAudio. Module. Cls(void); ~HSAudio. Module. Cls(void); public: int HSAudio. Module. Init(HSModule. Sender. Str *HSSender); void HSAudio. Module. Exit(void); void HSAudio. Module. MBHandler(HSSerial. Data. Str *data); void HSAudio. Module. HMIHandler(QJson. Object *data); void HSAudio. Module. Version(char vs. Buf[], unsigned int vs. Len); void HSAudio. Module. Test(void); }; #endif // HS_AUDIO_MODULE_CLS_H
Ø 服务的编写及逻辑流程 hs_audio_module_cls. cpp #include <QJson. Value> #include "hs_service_conf. h" #include <QDebug> HSAudio. Module. Cls: : HSAudio. Module. Cls(void) { } HSAudio. Module. Cls: : ~HSAudio. Module. Cls(void) { } int HSAudio. Module. Cls: : HSAudio. Module. Init(HSModule. Sender. Str *HSSender) { return this->HSAudio. Module. Func. Init(HSSender); } void HSAudio. Module. Cls: : HSAudio. Module. Exit(void) { this->HSAudio. Module. Func. Exit(); } void HSAudio. Module. Cls: : HSAudio. Module. MBHandler(HSSerial. Data. Str *data) { switch (data->Code) { case (ID_AUDIO_SOURCE_SET | ID_CMD_RESP_MASK): this->HSAudio. Set. Source. Back(data); break; case (ID_AUDIO_SOURCE_GET | ID_CMD_RESP_MASK): this->HSAudio. Get. Source. Back(data); break; default: break; } }
Ø 服务的编写及逻辑流程 void HSAudio. Module. Cls: : HSAudio. Module. HMIHandler(QJson. Object *data) { QString function; QJson. Value param; if(!get. Stirng(data, HS_REQUEST_NAME, function)) q. Debug("HSjson: : get. Stirng -> %s error!", HS_REQUEST_NAME); if(!get. Json. Value(data, HS_REQUEST_PARAM, param)) q. Debug("HSjson: : get. Json. Value -> %s error!", HS_REQUEST_PARAM); if(function == "set. Audio. Source"){ QJson. Array array = param. to. Array(); this->HSAudio. Set. Source(array[0]. to. Int(), array[1]. to. Int()); }else if(function == "get. Aduio. Source"){ this->HSAudio. Get. Source(); } } void HSAudio. Module. Cls: : HSAudio. Module. Version(char vs. Buf[], unsigned int vs. Len) { size_t len = strlen(HSModule. Version. Str); len = (len > vs. Len) ? vs. Len : len; memcpy(vs. Buf, HSModule. Version. Str, len); } void HSAudio. Module. Cls: : HSAudio. Module. Test(void) {} hs_audio_module_func. h #ifndef HS_AUDIO_MODULE_FUNC #define HS_AUDIO_MODULE_FUNC #include <QJson. Value> #include <QJson. Object> #include "hs_service_module. h“
Ø 服务的编写及逻辑流程 class HSAudio. Module. Func. Cls { public: HSAudio. Module. Func. Cls(void); ~HSAudio. Module. Func. Cls(void); public: int HSAudio. Module. Func. Init(HSModule. Sender. Str *HSSender); void HSAudio. Module. Func. Exit(void); public: int HSSend. Data. To. MB(unsigned int code, void *data, unsigned int len); int HSSend. Data. To. HMI(int HSPlugin. ID, const QString &attr. Name, QJson. Value param); void HSAudio. Set. Source(int source, int channel); void HSAudio. Set. Source. Back(HSSerial. Data. Str * data); }; hs_audio_module_func. cpp #include "hs_service_conf. h" #include "hs_audio_module_func. h“ HSAudio. Module. Func. Cls: : HSAudio. Module. Func. Cls(void) {} HSAudio. Module. Func. Cls: : ~HSAudio. Module. Func. Cls(void) {} int HSAudio. Module. Func. Cls: : HSAudio. Module. Func. Init(HSModule. Sender. Str*HSSender) { this->HSData. Sender = HSSender; this->HSAudio. Get. All. Info(); return HSModule. IDGroup; }
Ø 服务的编写及逻辑流程 void HSAudio. Module. Func. Cls: : HSAudio. Module. Func. Exit(void) { this->HSData. Sender = NULL; } int HSAudio. Module. Func. Cls: : HSSend. Data. To. MB(unsigned int code, void *data, unsigned int len) { return HSData. Sender>HSSend. Data(HSMODULE_NAME, HS_MAIN_BOARD_ENUM, HS_NORMAL_TASK_PRIORITY_ ENUM, code, 0 x 00, data, len); } int HSAudio. Module. Func. Cls: : HSSend. Data. To. HMI(int HSPlugin. ID, const QString &attr. Name, QJson. Value param) { QJson. Object obj; obj. insert(HS_ATTR_NAME, attr. Name); obj. insert(HS_ATTR_PARAM, param); obj. insert(HS_SERVICE_ID, ID_GROUP_AUDIO); obj. insert(HS_PLUGIN_ID, HSPlugin. ID); return HSData. Sender>HSSend. Data(HSMODULE_NAME, HS_HMI_CTL_ENUM, HS_NORMAL_TASK_PRIORITY_ENU M, HSPlugin. ID, 0 x 00, &obj, sizeof(obj)); } void HSAudio. Module. Func. Cls: : HSAudio. Set. Source(int source, int channel) { … data[0] = source; data[1] = channel; Audio. Frame = this->HSSend. Data. To. MB(ID_AUDIO_SOURCE_SET, data, 2); } void HSAudio. Module. Func. Cls: : HSAudio. Set. Source. Back(HSSerial. Data. Str *data){ … hs. Audio. Source = data->Data[0]; this->HSSend. Data. To. HMI(HSPlugin. ID, "audio. Source", QJson. Value(hs. Audio. Source)); }
- Slides: 25