【开源】基于Qt的跨平台插件式开发框架QCPFrame(一)
QCPFrame的接口文件在QCPFrame\interface文件夹下,包含CoreInterface和PluginInterface。其中CoreInterface用于定义QCPF_Model要实现的功能,而PluginInterface用于定义所有Plugin要实现的功能。这意味着Core与Plugin之间可以通过这些接口互相访问。
CoreInterface接口主要代码如下:
class QCPF_Interface : public QObject
{
Q_OBJECT
public:
/**********************************************************************************
* 系统组件:
* 1. 用以扩展系统功能,在加载时,首先被加载,其余Plugins为非系统组件。
* 2. 系统组件可以选择哪些可用哪些不可用,这可以用于用户权限管理等功能
* 3. 系统为单例组件,可排序,但是不容许被克隆。
**********************************************************************************/
RunMode I_RunMode;
//所有系统组件集合
QList I_SysPlugins;
//所有被选中的系统组件集合
QList I_SysPlugins_Sel;
/**********************************************************************************
* 非系统组件:
* 1. 用以实现业务层功能,在系统组件加载完成过后被加载。
* 2. 非系统组件可以选择哪些可用哪些不可用,这可以用于用户权限管理等功能
* 3. 非系统组件可排序,可以被克隆。
**********************************************************************************/
//非系统原始组件集合
QList I_NSysOrigPlugins;
//被选中的非系统原始组件集合
QList I_NSysOrigPlugins_Sel;
//克隆组件集合,克隆组件必须是从I_NSysOrigPlugins_Sel中生成的副本
QList I_NSysClonePlugins;
//包括已选择的原始组件和克隆组件在内的所有非系统组件的集合
QList I_NSysAllValidPlugins;
//=====================当前配置文件目录和组件目录
QString I_SystemID;
QString I_SystemName;
QString I_SystemVersion;
QString I_OrganizationName;
QString I_ApplicationDirPath;
QString I_SystemPluginDirPath;
QString I_NonSysPluginDirPath;
QString I_ConfigDirPath;
QString I_ConfigFileName;
QString I_ConfigFullFilePath;
//================================================Users
//用户信息
QList I_UserInfoLst;
UserInfo I_CurrentUserInfo;
//================================================SharedMemory
//组件间共享内存
bool I_SMBoolVar1;
bool I_SMBoolVar2;
int I_SMIntVar1;
int I_SMIntVar2;
double I_SMDoubleVar1;
double I_SMDoubleVar2;
QString I_SMStrVar1;
QString I_SMStrVar2;
QObject I_SMObject1;
QObject I_SMObject2;
QList I_SMObjectLst;
QVector I_SMObjectVec;
QQueue I_SMObjectQue;
//Thead
QThreadPool I_SMThreadPool;
QThread I_SMThread;
QMutex I_SMMutex;
QReadWriteLock I_SMReadWriteLock;
QSemaphore I_SMSemaphore;
QWaitCondition I_SMWaitCondition;
signals:
int sig_OutputInfo(tagOutputInfo& info);
int sig_Core(QVariant arg_in, QVariant &arg_out);
public slots:
virtual int slot_InputInfo(tagOutputInfo& info) { return 0; }
virtual int slot_Core(QVariant arg_in, QVariant &arg_out) { return 0; }
virtual int Invoke_PluginFunction(PluginType pType, QString pluginID, QString pluginFunctionName, QVariant arg_in, QVariant& arg_out) { return 0; }
virtual int Invoke_PluginFunction(PluginType pType, QString pluginID, QString copyID, QString pluginFunctionName, QVariant arg_in, QVariant& arg_out) { return 0; }
};
如上所示,CoreInterface定义了内核要实现的成员变量,信号及槽。
enum InfoType
{
INFT_INITIALIZE_FINISHED,
INFT_MSG_INFO,
INFT_MSG_WARN,
INFT_MSG_ERROR,
INFT_MSG_QUESTION,
INFT_STATUS_INFO,
INFT_APPLICATION_CLOSE,
INFT_WRITE_LOG,
INFT_PLUGIN_COLLECT,
INFT_PLUGIN_COLLECT_FINISHED,
INFT_CORE_CONFIG_CHANGED,
INFT_VIEW_CONFIG_CHANGED,
INFT_PLUGIN_BROADCAST,//表示组件发起了事件广播,广播内容见参数
INFT_PLUGIN_SPECIAL,//表示组件向另一个指定组件发送消息,消息内容见参数
INFT_STATUSBAR_TEMP,
INFT_LOG_ACTION,
INFT_LOG_ERROR,
};
struct tagOutputInfo
{
public:
InfoType _type;
QString _title;
QString _content;
int _timeout;
tagOutputInfo(){}
tagOutputInfo(InfoType type, QString title, QString content){ _type=type;_title=title;_content=content;}
tagOutputInfo(InfoType type, QString title, QString content, int timeout){ _type=type;_title=title;_content=content; _timeout=timeout;}
};
tagOutputInfo消息结构如上所示,可以看到,我们可以通过该结构体承载任意消息类型,当Core的slot_InputInfo槽与组件的sig_OutputInfo信号绑定后,一旦检测到信号,Core会根据消息类型进行不同的处理,这是QCPFrame消息传输的主要思路,这种形式也便于后期消息类型扩展。至于不同的类型消息在内核里如果被处理,请关注后续QCPF_Model的相关介绍。
PluginInterface接口主要代码如下:
class Plugin_Interface:public QObject
{
Q_OBJECT
public:
QString I_PluginID;//组件ID,该属性是组件间唯一的
PluginType I_PluginType;//组件类型,系统组件或非系统组件
QString I_PluginAliasName;//组件别名
QString I_PluginVersion;//组件版本
QString I_PluginAuther;//组件开发者
QString I_PluginComment;//组件功能说明
QString I_PluginFilePath;//组件路径
QVariant I_PluginTag;//组件类型,用于区别业务类型或者结构类型
AuthorityType I_PluginAuthority;//组件的访问权限
bool I_IsEnable;//是否被选中
bool I_IsCopy;//我是谁?我是不是一个克隆体?
QString I_CopyID;//副本ID,该属性是副本间唯一的
QString I_CopyAliasName;//副本别名
QString I_CopyComment;//副本功能说明
QVariant I_PluginVar;//通用组件变量
QList I_PluginVarList;//通用组件变量集合
QList I_ActionList;//通用组件Action集合
QList I_FunctionList;//通用组件Function集合
QVector I_WidgetList;//通用组件部件集合
public:
virtual Plugin_Interface* Clone(QString copyID, QString copyAliasName, QString copyComment) {return nullptr;}
virtual bool ConnectCore(QObject* core) { return true; }
virtual int PluginFunction(QVariant arg_in, QVariant &arg_out) { return 0; }
virtual void InitActionList(Plugin_Interface* plugin){};
virtual void InitFunctionList(Plugin_Interface* plugin){};
virtual void InitWidgetList(Plugin_Interface* plugin){};
signals:
int sig_OutputInfo(tagOutputInfo& info);
int sig_Plugin(QVariant arg_in, QVariant &arg_out);
public slots:
virtual int slot_InputInfo(tagOutputInfo& info) { return 0; }
virtual int slot_Plugin(QVariant arg_in, QVariant &arg_out) { return 0; }
virtual void slot_Action(bool checkState) { }
//当core初始化时要执行的过程
virtual int OnCoreInitialize() { return 0; }
//当view视图构造完成后,Load前要执行的过程
virtual int OnViewCreated() { return 0; }
//当view视图Load时要执行的过程
virtual int OnViewLoaded() { return 0; }
//当view视图Closeing时要执行的过程
virtual int OnViewClosing() { return 0; }
};
以上定义了作为一个QCPFrame的组件必须要实现的功能。成员变量后面有明确的注释,其中I_ActionList,I_FunctionList,I_WidgetList是后期UI配置的主要数据来源。
具体来说,InitActionList,InitFunctionList,InitWidgetList分别用于组件I_ActionList,I_FunctionList,I_WidgetList的初始化,典型的应用是当QCPF_Model完成组件收集以后,ViewEditor(一个特殊用途的系统组件)通过接口获取目标组件的这些资源,并将他们展示给用户,用户可以通过ViewEditor的功能对主框架UI进行编辑,保存,用以实现主界面UI可配。
接口提供了QCPFrame完整生命周期内,不同阶段的槽,用于组件初始化,响应,及内存回收。
本节主要讲了QCPFrame的内核及组件接口设计,这些接口尽量以通用,可扩展,可裁剪为主要设计思路,后续会讲一讲组件的开发流程,谢谢关注。
【QQ】: 260271262
【开源】基于Qt的跨平台插件式开发框架QCPFrame(三)