01u-00-bean-认识bean模块

1. 重点内容

  • 解释bean是什么。
  • 如何得到一个模块的BeanConfig及Bean。
  • 一个模块的BeanConfig及Bean是如何销毁。

2. 运行展示

 3. 程序示例

3.1 什么是bean

模块化是我们构建复杂系统的一种简单方法,它是复杂的东西抽象成可以理解的简单化的具体体现,bean就是想通过将各种系统所需要的东西通过抽象组合成简单的模块,bean模块管理模块化的东西,bean它可以是抽象的任何有用的东西,在peanutlib中抽象的bean模块就有application模块,bean模块,db模块,xml模块,json模块,log模块等,每个模块即独立完成自己应该做的事情,又可以协作完成更加复杂的事情。

我们知道对象的分工协作构成了一个模块,在定义一个模块时,将模块看成BeanConfig,将对象看成Bean,我们将整个系统看成是BeanConfig与Bean的集合。我们通过下图来举一个例子,下图我们将整体看一个系统,该系统有3个模块,分别是A模块(bean1,bean2,bean3 对象),B模块(bean1,bean2 对象),C模块(bean1,bean2 对象),每个模块用beanConfig来表示。

 peanut_appconfig.xml配置文件是专门用来配置peanutlib的BeanConfig与Bean,下面是一个日志模块的例子。  

<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标签(logBeanConfigSample):日志模块的BeanConfig。

    id:日志模块的唯一标识。

name:模块名称。

    className: log模块的BeanConfig的类名

type:模块类型。

  • bean标签(logBean_1):日志模块的bean,它对应的是peanut::PlQtLogController对象,该对象是用QLog日志输出框架。 另外在bean标签中定义该对象的初始属性及值。

   

  • bean标签(logBean_2):日志模块的bean,它对应的是peanut::PlLog4qtController对象,该对象是用log4qt日志输出框架。  另外在bean标签中定义该对象的初始属性及值。

3.2 如何得到一个模块的BeanConfig及Bean

通常模块BeanConfig与Bean是已设计并实现,如果要得到一个已实现的BeanConfig与Bean,来为正在编辑的代码服务,在程序中如何实现?

下在我们通过一个例子来说明,这个例子是使用日志模块,从BeanConfig中得到它对应的日志模块及该模块对应的Bean,用Bean产生两种不同日志框架的输出。

首先我们用00u的项目工程代码“pssample00u0”来创建一个项目的基本环境,当然我们不能直接用pssample00u0来创建,要新创建一个工程代码“pssample01u0”,再将pssample00u0的程序及程序资源复制到当前目录中。

  • 修改pssample00u0.pro文件

#生成目标

CONFIG(release, debug|release) {

    #realease模式下的目标文件

    TARGET = psample01u0

} else {

    #debug模式下的目标文件

    TARGET = psample01u0d

}

注:将生成目标改成pssample01u0

  • 新建“PsBean00MainWindow”窗口,演示如何使用日志模块

在peanut_appconfig.xml文件中一个标签beanConfig,该标签描述的日志模块 

<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>

下面是我们通过日志模块的配置项,来使用该模块的服务。

  • 头文件ps_bean00_mainwindow.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 PS_BEAN00_MAINWINDOW_H
#define PS_BEAN00_MAINWINDOW_H

#include <QMainWindow>
#include <QTextCharFormat>

namespace peanut {

namespace Ui {
class PsBean00MainWindow;
}

class PsBean00MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit PsBean00MainWindow(QWidget *parent = nullptr);
    ~PsBean00MainWindow();

    enum LogTypeFlag {
        debug = 0x1,
        info = 0x2,
        warn = 0x3,
        error = 0x4,
        fatal = 0x5
    };
    Q_DECLARE_FLAGS(LogTypeFlags, LogTypeFlag)

private slots:
    void on_btnLogBean1_clicked();

    void on_btnLogBean2_clicked();

    //输出日志到界面
    void writeLog(const QString &logText, int flag);
private:
    Ui::PsBean00MainWindow *ui;

    int m_logRowCount=0;  //行数

    QTextCharFormat     m_debugTextFormat;
    QTextCharFormat     m_infoTextFormat;
    QTextCharFormat     m_warnTextFormat;
    QTextCharFormat     m_errorTextFormat;
    QTextCharFormat     m_fatalTextFormat;
};

}

#endif // PS_BEAN00_MAINWINDOW_H
  • 程序文件ps_bean00_mainwindow.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_application.h"
#include "ps_bean00_mainwindow.h"
#include "ui_ps_bean00_mainwindow.h"

#include <pl_log.h>


namespace peanut {

PsBean00MainWindow::PsBean00MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::PsBean00MainWindow)
{
    ui->setupUi(this);

    ui->plainTextEdit->setReadOnly(true);

    m_debugTextFormat.setForeground(QBrush(Qt::black));
    m_infoTextFormat.setForeground(QBrush(Qt::blue));
    m_warnTextFormat.setForeground(QBrush(Qt::darkRed));
    m_errorTextFormat.setForeground(QBrush(Qt::red));
    m_fatalTextFormat.setForeground(QBrush(Qt::gray));
}

PsBean00MainWindow::~PsBean00MainWindow()
{
    delete ui;
}

void peanut::PsBean00MainWindow::on_btnLogBean1_clicked()
{
    //QLog日志框架
    PlQtLogController *log = nullptr;
    //得到app对象
    PsApplication *app = PsApplication::getPsApplication();
    try{
        //从app对象得到BeanConfig
        //参数1:logBeanConfigSample,对应peanut_appconfig.xml中beanConfig的id
        //参数2:logBean_1,对应peanut_appconfig.xml中beanConfig的id=logBeanConfigSample,从属bean的id=logBean_1
        QObject *obj = app->getBean("logBeanConfigSample", "logBean_1");
        if(obj!=nullptr) {
            //将obj对象转换成PlQtLogController对象
            log = qobject_cast<PlQtLogController*>(obj);
        }
        else {
            throw PeanutError(QObject::tr("PS示例模块异常:%1").arg(app->getError()));
        }
        if(log!=nullptr) {
            QString logText = tr("[logBean_1]-[INFO日志]-当前设备001号运行状态正常...");
            log->info(logText);  //输出到控件台
            writeLog(logText, info); //输出到界面

            logText =  tr("[logBean_1]-[DEBUG日志]-当前设备001号运行状态正常...");
            log->info(logText);  //输出到控件台
            writeLog(logText, debug); //输出到界面

            logText =  tr("[logBean_1]-[WARN日志]-当前设备003号运行状态异常,无法连接该设备...");
            log->warn(logText);  //输出到控件台
            writeLog(logText, warn); //输出到界面

            logText =  tr("[logBean_1]-[INFO日志]-当前设备005号运行状态错误,未启动A控制器...");
            log->error(logText);  //输出到控件台
            writeLog(logText, error); //输出到界面

            logText =  tr("[logBean_1]-[FATAl日志]-当前设备008号运行状态已严重错误,导致所有设备运行停止...");
            //log->fatal(logText);  //输出到控件台
            writeLog(logText, fatal); //输出到界面
        }
    } catch(PeanutError err) {
        //如果异常,输出到系统运行日志
        LOG_ERROR(PlBaseApplication::getGlobalLogger(), err.what());
        PlMessageBox::warning(this, tr("异常警告信息"), err.what());
    }
}

void peanut::PsBean00MainWindow::on_btnLogBean2_clicked()
{
    //Log4qt日志框架
    PlLog4qtController *log = nullptr;
    //得到app对象
    PsApplication *app = PsApplication::getPsApplication();
    try{
        //从app对象得到BeanConfig
        //参数1:logBeanConfigSample,对应peanut_appconfig.xml中beanConfig的id
        //参数2:logBean_2,对应peanut_appconfig.xml中beanConfig的id=logBeanConfigSample,从属bean的id=logBean_2
        QObject *obj = app->getBean("logBeanConfigSample", "logBean_2");
        if(obj!=nullptr) {
            //将obj对象转换成PlQtLogController对象
            log = qobject_cast<PlLog4qtController*>(obj);
        }
        else {
            throw PeanutError(QObject::tr("PS示例模块异常:%1").arg(app->getError()));
        }
        if(log!=nullptr) {
            QString logText = tr("[logBean_2]-[INFO日志]-当前设备003号运行状态正常...");
            log->info(logText);  //输出到控件台
            writeLog(logText, info); //输出到界面

            logText =  tr("[logBean_2]-[DEBUG日志]-当前设备005号运行状态正常...");
            log->info(logText);  //输出到控件台
            writeLog(logText, debug); //输出到界面

            logText =  tr("[logBean_2]-[WARN日志]-当前设备007号运行状态异常,无法连接该设备...");
            log->warn(logText);  //输出到控件台
            writeLog(logText, warn); //输出到界面

            logText =  tr("[logBean_2]-[INFO日志]-当前设备002号运行状态错误,未启动A控制器...");
            log->error(logText);  //输出到控件台
            writeLog(logText, error); //输出到界面

            logText =  tr("[logBean_2]-[FATAl日志]-当前设备009号运行状态已严重错误,导致所有设备运行停止...");
            //log->fatal(logText);  //输出到控件台
            writeLog(logText, fatal); //输出到界面
        }
    } catch(PeanutError err) {
        //如果异常,输出到系统运行日志
        LOG_ERROR(PlBaseApplication::getGlobalLogger(), err.what());
        PlMessageBox::warning(this, tr("异常警告信息"), err.what());
    }
}

void PsBean00MainWindow::writeLog(const QString &logText, int flag)
{
    if(flag == LogTypeFlag::debug) {
        ui->plainTextEdit->mergeCurrentCharFormat(m_debugTextFormat);
    }
    if(flag == LogTypeFlag::info) {
        ui->plainTextEdit->mergeCurrentCharFormat(m_infoTextFormat);
    }
    if(flag == LogTypeFlag::warn) {
        ui->plainTextEdit->mergeCurrentCharFormat(m_warnTextFormat);
    }
    if(flag == LogTypeFlag::error) {
        ui->plainTextEdit->mergeCurrentCharFormat(m_errorTextFormat);
    }
    if(flag == LogTypeFlag::fatal) {
        ui->plainTextEdit->mergeCurrentCharFormat(m_fatalTextFormat);
    }
    ui->plainTextEdit->appendPlainText(QString("[%1]-").arg(++m_logRowCount) + logText);
}

}
  • 设计UI文件ps_bean00_mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>peanut::PsBean00MainWindow</class>
 <widget class="QMainWindow" name="peanut::PsBean00MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>bean示例-使用bean</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string/>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <spacer name="horizontalSpacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>40</width>
           <height>20</height>
          </size>
         </property>
        </spacer>
       </item>
       <item>
        <widget class="QPushButton" name="btnLogBean1">
         <property name="text">
          <string>bean:logBean_1操作</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QPushButton" name="btnLogBean2">
         <property name="text">
          <string>bean:logBean_2操作</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox_2">
      <property name="title">
       <string/>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
        <widget class="QPlainTextEdit" name="plainTextEdit"/>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

  • 将PsBean00MainWindow窗口挂到主窗口ps_mainwindow中

 修改ps_mainwindow.cpp中的on_trigrMenu方法

void PsMainWindow::on_trigerMenu(QAction *action)
{
    PsApplication *app = PsApplication::getPsApplication();
    if(action != nullptr) {
        QIcon icon;
        int cur;
        //得到菜单ui->menubar当前响应的单击的action对象,并得到它的对象名称
        QString actName = action->objectName();        
        if(actName=="act_PlLogForm") {   //识别是act_PlLogForm对象
            if(this->m_logForm==nullptr) {
                m_logForm = app->getGlobalLogForm();
            }
            icon = m_logForm->windowIcon();
            if(icon.isNull()) {  //如果m_logForm对象的图标为空
                cur = ui->tabWidget->addTab(m_logForm, m_logForm->windowTitle());
            }
            else {
                //增加m_logForm对象到Tab页中
                cur = ui->tabWidget->addTab(m_logForm, icon, m_logForm->windowTitle());
            }
            m_logForm->show();
            ui->tabWidget->setCurrentIndex(cur);  //设置TabWidget的当前页
            ui->tabWidget->setVisible(true);
        }
        else if(actName=="act_PsBean00MainWindow") {
            PsBean00MainWindow *widget = new PsBean00MainWindow(this);
            icon = widget->windowIcon();
            widget->setAttribute(Qt::WA_DeleteOnClose); //关闭时自动删除
            if(icon.isNull()) {
                cur = ui->tabWidget->addTab(widget, widget->windowTitle());
            }
            else {                
                cur = ui->tabWidget->addTab(widget, icon, widget->windowTitle());
            }
            ui->tabWidget->setCurrentIndex(cur);
            ui->tabWidget->setVisible(true);
        }
    }
}

4. 代码下载

代码下载链接:https://pan.baidu.com/s/12Qy7q6kHsu6q2MIi1errxQ

Peanutlib项目演示程序下载:peanut_pwdis: pwdis是QT应用系统开发框架(C++),采用分层模块化设计,底层peanutlib按模块封装方便易用的类库及API(xml,db,appconfig,log,grid,json,bean等十几个),应用层提供部门人员权限及报表等,还提供了开发中常用的组件使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

积木虎

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

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

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

打赏作者

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

抵扣说明:

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

余额充值