1. 重点内容
- 在peanut_appconfig.xml中自定义模块的配置项。
- 程序实现自定义模块。
- 使用自定义模块。
2. 运行展示
3. 程序示例
我们要实现一个自定义模块,首先要认识到一个项目对应的是一个模块,也就是只需要一个BeanConfig,例如,PsSample01u0项目,它对应的是一个BeanConfig,该BeanConfig对应可以是多个Bean(注:bean对象不一定是模块中的所有对象,它通常是对外发布的接口对象),BeanConfig取名为了好识别,最好是与项目名相似,PsSample01u0项目,取的BeanConfig名称PsSampleBeanConfig。
项目工程是在“01u-00-bean-认识bean模块”项目工程基础上修改,仍使用PsSample01u0项目,下面详细介绍。
3.1 在peanut_appconfig.xml中自定义模块的配置项
Peanut_appconfig.xml配置文件是peanutlib框架的配置项,自定义一个模块我们要在该配置项的<customBeanConfig>标签中定义,该标签是为用户自定义模块配置的,下面是在项目工程PsSample01u0项目中加入一个PsSampleBeanConfig模块的配置。
- 配置文件peanut_appconfig.xml
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<peanut>
<config>
<globalConfig>
<beanConfig chooseBeanId="logBeanQtlog" className="peanut::PlLogBeanConfig" id="logBeanConfigSample" name="LogModule" type="Log">
<bean isDebug="true" className="peanut::PlQtLogController" isWarn="true" id="logBean_1" name="" isSendSingal="true" isLogForm="false" isError="true" isConversionPattern="true" isFatal="true" isInfo="true" type="QLog"/>
<bean className="peanut::PlLog4qtController" id="logBean_2" filePath="./config/log4qt.conf" name="" isSendSingal="true" isLogForm="false" isConversionPattern="true" type="Log4qt"/>
</beanConfig>
<beanConfig chooseBeanId="" className="peanut::PlXmlDomBeanConfig" id="xmlBeanConfigSample" name="XmlModule" type="Xml">
<bean rootElement="peanut" className="peanut::PlXmlDomWriter" id="xmlDomWriterBeanAppConfig" name="" filePathName="./config/peanut_appconfig.xml" levelSplit="." type="XmlDomWriter"/>
</beanConfig>
<beanConfig chooseBeanId="" className="peanut::PlDBBeanConfig" id="dbBeanConfigSample" name="DBModule" type="DB">
<bean connectOptions="" userName="" port="" className="peanut::PlDBController" hostName="" id="sqliteDBBeanSample" description="" isEncrypt="false" name="sqliteDBBeanSample" databaseName="./db/peanutsample.db" password="" type="QSQLITE">
</bean>
</beanConfig>
<beanConfig className="peanut::PlDictBeanConfig" id="dictBeanConfigSample" name="DictModule" type="Dict">
<bean className="peanut::PlDictCtrl" id="dictBeanSkin" valueMap=":/qlightstyle/lightstyle.qss|:/qdarkstyle/style.qss|:/qss/flatblack.css|:/qss/flatwhite.css|:/qss/lightblue.css" key="style" value=":/qss/lightblue.css" type="Skin"/>
<bean value="255,0,0" name="控件图标颜色" key="iconColor" type="widgetIconColor" className="peanut::PlDictCtrl" id="dictBeanWidgetIconColor"/>
<bean value="Microsoft YaHei,10" name="缺省应用字体" key="appFont" type="appFont" className="peanut::PlDictCtrl" id="dictBeanAppFont"/>
<bean className="peanut::PlDictCtrl" id="dictBeanAppName" name="应用名称" key="appName" value="peanutSample" type="appAttribute"/>
<bean className="peanut::PlDictCtrl" id="dictBeanKeyGenName" name="注册名称" key="keyGenName" value="wangrq" type="appAttribute"/>
<bean className="peanut::PlDictCtrl" id="dictBeanSerialNumber" name="序列号" key="serialNumber" value="" type="appAttribute"/>
<bean className="peanut::PlDictCtrl" id="dictBeanFilePathName" name="注册文件名称" key="filePathName" value="." type="appAttribute"/>
<bean className="peanut::PlDictCtrl" name="试用注册文件名称" key="filePathName" type="appAttribute" value="." id="dictBeanTrialFilePathName"/>
<bean className="peanut::PlDictCtrl" id="dictBeanAppSystemName" name="系统名称" key="appSystemName" value="peanutlib示例程序" type="appAttribute"/>
</beanConfig>
<beanConfig chooseBeanId="" className="peanut::PlServiceProxyBeanConfig" id="serviceProxyBeanConfigSample" name="serviceProxyBeanConfig" type="ServiceProxy">
<bean className="peanut::PlServiceProxyCtrl" id="serviceProxyBean" name="serviceProxyBean" type="ServiceProxy">
</bean>
</beanConfig>
</globalConfig>
<customBeanConfig>
<beanConfig id="psSampBeanConfig" name="示例模块" type="PsSample" className="PsSampBeanConfig" sort="1" >
<bean id="psSampleBean" name="psSampleBean" type="sample" className="peanut::PsSampBeanCtrl" colorAttr="139,0,139" textValue="示例模块Bean输出测试字符"/>
</beanConfig>
</customBeanConfig>
</config>
</peanut>
注:下面在customBeanConfig标签中,配置id="psSampBeanConfig",对应的类名className="PsSampBeanConfig" 的BeanConfig模块。
<customBeanConfig>
<beanConfig id="psSampBeanConfig" name="示例模块" type="PsSample" className="PsSampBeanConfig" sort="1" >
<bean id="psSampleBean" name="psSampleBean" type="sample" className="peanut::PsSampBeanCtrl" colorAttr="139,0,139" textValue="示例模块Bean输出测试字符"/>
</beanConfig>
</customBeanConfig>
PsSampBeanConfig模块配置一个Bean对象,className="peanut::PsSampBeanCtrl",注意它有两个属性colorAttr="139,0,139" textValue="示例模块Bean输出测试字符",我们在示例程序中,会取到它并显示出来。
3.2 程序实现自定义模块
在“PsSample01u0”项目工程中,新增一个C++ class程序,ps_beanconfig。
- 头文件ps_beanconfig.h
/***************************************************************************
* This file is part of the Peanut Library project *
* Copyright (C) 2022 by Wang Ren Qian *
* author:积木虎 154318869@qq.com *
* Peanut Software Studio *
****************************************************************************/
#ifndef PSBEANCONFIG_H
#define PSBEANCONFIG_H
#include <QObject>
#include <pl_bean.h>
namespace peanut {
//示例模块的一个Bean对象
class PsSampBeanCtrl : public QObject
{
Q_OBJECT
public:
PsSampBeanCtrl(QObject *parent = nullptr);
~PsSampBeanCtrl();
public:
QString colorAttr() const;
void setColorAttr(const QString &colorAttr);
QString textValue() const;
void setTextValue(const QString &textValue);
QColor getTextColor();
private:
QString m_colorAttr="255,0,0";
QString m_textValue;
};
//为本项目自定义一个示例模块,命名为Samp,类名PsSampBeanConfig
class PsSampBeanConfig : public PlBaseBeanConfig
{
Q_OBJECT
public:
PsSampBeanConfig(QObject *parent = nullptr);
~PsSampBeanConfig();
public:
//使用ID取对象,注:该对象一次性创建,生命周期是整个Application,无需程序员手工delete
QObject *getBean(const QString &id) override;
//使用ID新new一个对象,注:该对象生命周期由参数2 object决定
//参数2:如果object为空,该生命周期由程序员手工控制
QObject *newBean(const QString &id, QObject *object=nullptr) override;
protected:
//创建BeanConfig开始
void createBegin() override;
//创建BeanConfig
void create() override;
//创建BeanConfig结束
void createEnd() override;
//注册本BeanConfig
void registerBean(PlBeanConfigInfo &beanConfigInfo) override;
};
}
#endif // PSBEANCONFIG_H
- 程序文件ps_beanconfig.cpp
/***************************************************************************
* This file is part of the Peanut Library project *
* Copyright (C) 2022 by Wang Ren Qian *
* author:积木虎 154318869@qq.com *
* Peanut Software Studio *
****************************************************************************/
#include "ps_beanconfig.h"
#include "pl_utils.h"
#include "pl_application.h"
namespace peanut {
//注册PsSampBeanConfig类
REGISTER(PsSampBeanConfig);
PsSampBeanConfig::PsSampBeanConfig(QObject *parent)
: PlBaseBeanConfig(parent)
{
}
PsSampBeanConfig::~PsSampBeanConfig()
{
}
QObject *PsSampBeanConfig::getBean(const QString &id)
{
QObject *obj = this->getBeanObject(id);
//如果未取到指定id的对象
if(obj==nullptr) {
//新new一个对象
obj = this->newBean(id, this);
if(obj==nullptr) return nullptr;
//将该对象入栈保存
this->insertBeanObject(id, obj);
}
return obj;
}
QObject *PsSampBeanConfig::newBean(const QString &id, QObject *object)
{
//new一个指定ID的对象
QObject *obj = PlBaseBeanConfig::newBean(id, object);
if(obj!=nullptr) { //如果成功new
//如果该对象是PsSampBeanCtrl
if(obj->inherits("peanut::PsSampBeanCtrl")) {
//转换该对象为PsSampBeanCtrl对象
PsSampBeanCtrl *bean = qobject_cast<PsSampBeanCtrl*>(obj);
if(bean==nullptr) {
m_error = QObject::tr("PS示例模块-beanConfig异常:转换id=[%1]bean的PsSampBeanCtrl对象失败").arg(id);
LOG_ERROR(PlBaseApplication::getGlobalLogger(), m_error);
return nullptr;
}
//取到指定ID在peanut_appconfig中配置的属性及值
PlBeanInfo beanInfo = this->getBeanConfigInfo().getBeanInfo(id);
if(beanInfo.id()!=id) {
delete bean;
m_error = QObject::tr("PS示例模块-beanConfig异常:没有取到id=[%1]的bean值").arg(id);
LOG_ERROR(PlBaseApplication::getGlobalLogger(), m_error);
return nullptr;
}
//转换成map
QMap<QString,QString> map = beanInfo.attrMap();
//PsSampBeanCtrl对象的属性colorAttr赋值
bean->setColorAttr(map.value("colorAttr"));
//PsSampBeanCtrl对象的属性textValue赋值
bean->setTextValue(map.value("textValue"));
return bean;
}
else {
delete obj;
obj = nullptr;
m_error = QObject::tr("PS示例模块-beanConfig异常:id=[%1]的bean未注册").arg(id);
LOG_ERROR(PlBaseApplication::getGlobalLogger(), m_error);
}
}
return obj;
}
void PsSampBeanConfig::createBegin()
{
Q_ASSERT(PlBaseApplication::getGlobalAppConfig()!=nullptr);
LOG_INFO(PlBaseApplication::getGlobalLogger(), QObject::tr("PS示例模块-PsSampBeanConfig:已开始创建..."));
}
void PsSampBeanConfig::create()
{
//必须注册m_beanConfigInfo,注:m_beanConfigInfo已由peanutlib初始化
registerBean(m_beanConfigInfo);
}
void PsSampBeanConfig::createEnd()
{
LOG_INFO(PlBaseApplication::getGlobalLogger(), QObject::tr("PS示例模块-PsSampBeanConfig:已创建完成..."));
}
void PsSampBeanConfig::registerBean(PlBeanConfigInfo &beanConfigInfo)
{
Q_ASSERT(PlBaseApplication::getGlobalLogger()!=nullptr);
//注册BeanConfigInfo
PlBaseBeanConfig::registerBean(beanConfigInfo);
//注册示例模块的bean
foreach( PlBeanInfo info, beanConfigInfo.getBeanInfos() ) {
if(info.className()=="peanut::PsSampBeanCtrl") {
BeanFactory::registerClass<peanut::PsSampBeanCtrl>();
LOG_INFO(PlBaseApplication::getGlobalLogger(), QObject::tr("PS示例模块-beanConfig:PsSampBeanCtrl已注册id=[%1]Bean[peanut::PsSampBeanCtrl]").arg(info.id()));
}
}
}
PsSampBeanCtrl::PsSampBeanCtrl(QObject *parent)
: QObject(parent)
{
}
PsSampBeanCtrl::~PsSampBeanCtrl()
{
}
QString PsSampBeanCtrl::colorAttr() const
{
return m_colorAttr;
}
void PsSampBeanCtrl::setColorAttr(const QString &colorAttr)
{
m_colorAttr = colorAttr;
}
QString PsSampBeanCtrl::textValue() const
{
return m_textValue;
}
void PsSampBeanCtrl::setTextValue(const QString &textValue)
{
m_textValue = textValue;
}
QColor PsSampBeanCtrl::getTextColor()
{
return PlQIconUtils::getColor(m_colorAttr);
}
}
3.3 使用自定义模块
如何在程序中使用PsSampBeanConfig,我们在PsBean00MainWindow窗口程序中实现,实现效果是在窗口中将Bean的属性colorAttr="139,0,139" textValue="示例模块Bean输出测试字符"显示出来。
- 修改设计文件ps_bean00_mainwindow.ui
- 修改头文件ps_bean00_mainwindow.h,ps_bean00_mainwindow.cpp,加入下面的方法
void peanut::PsBean00MainWindow::on_btnSampBean_clicked()
{
//自定义PsSampBeanConfig模块,PsSampBeanCtrl是该模块的Bean
PsSampBeanCtrl *bean = nullptr;
//得到app对象
PsApplication *app = PsApplication::getPsApplication();
try{
//从app对象得到BeanConfig
//参数1:psSampBeanConfig,对应peanut_appconfig.xml中beanConfig的id
//参数2:psSampleBean,对应peanut_appconfig.xml中beanConfig的id=psSampBeanConfig,从属bean的id=psSampleBean
QObject *obj = app->getBean("psSampBeanConfig", "psSampleBean");
if(obj!=nullptr) {
//将obj对象转换成PlQtLogController对象
bean = qobject_cast<PsSampBeanCtrl*>(obj);
}
else {
throw PeanutError(QObject::tr("PS示例模块异常:%1").arg(app->getError()));
}
if(bean!=nullptr) {
QColor color = bean->getTextColor();
QTextCharFormat textFormat;
textFormat.setForeground(QBrush(color));
ui->plainTextEdit->mergeCurrentCharFormat(textFormat);
ui->plainTextEdit->appendPlainText(QString("[%1]-").arg(++m_logRowCount) + QString("[取PsSampBeanCtrl的textValue = %1]-[取PsSampBeanCtrl的colorAttr = %2])").arg(bean->textValue()).arg(bean->colorAttr()));
}
} catch(PeanutError err) {
//如果异常,输出到系统运行日志
LOG_ERROR(PlBaseApplication::getGlobalLogger(), err.what());
PlMessageBox::warning(this, tr("异常警告信息"), err.what());
}
}
4. 代码下载
代码下载链接: https://pan.baidu.com/s/1FI8ZK3R21ftAgJC_WRv6cQ?pwd=kmni 提取码: kmni
Peanutlib项目演示程序下载:peanut_pwdis: pwdis是QT应用系统开发框架(C++),采用分层模块化设计,底层peanutlib按模块封装方便易用的类库及API(xml,db,appconfig,log,grid,json,bean等十几个),应用层提供部门人员权限及报表等,还提供了开发中常用的组件使用。