01u-01-bean-自定义一个模块

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等十几个),应用层提供部门人员权限及报表等,还提供了开发中常用的组件使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积木虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值