03u-00-db-DB模块的配置

1. 重点内容

  • 配置项说明
  • 建立多数据源
  • 加密配置项

2. 运行展示

3. 程序示例

 DB模块主要是对数据库的操作,它是纯Qt上的封装,不涉及第三方的库,Qt操作数据库主要是QSqlDatabase,QSqlQuery,QSqlRecord对象,在此基础上将这些对象的协作简化成API来完成,请看以下API说明:

  //打开数据库
    bool open();
    //数据库是否打开
    bool isOpen();
    //type指定的支持驱动类型是否存在
    bool isDriverSupport(const QString &type);
    //关闭数据库
    void close();
    //取指定select语句中列名的列号
    int queryGetColumnNo(const QSqlQuery &query, const QString &column);
    //取指定select语句中列号的列名
    QString queryGetColumnName(const QSqlQuery &query, const int &columnNo);
    //取指定select语句中所有字段名称
    QStringList queryGetColumnNames(const QSqlQuery &query);
    //取记录数
    int queryRowCount(const QSqlQuery &query);
    int queryColumnCount(const QSqlQuery &query);
    //取指定select语句的值
    QVariant queryValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是整型
    int queryIntValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是长整型
    long queryLongValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是单精度型
    float queryFloatValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是双精度型
    double queryDoubleValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是布尔型
    bool queryBoolValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是字符串型
    QString queryStringValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是日期型
    QDate queryDateValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是日期时间型
    QDateTime queryDateTimeValue(const QSqlQuery &query, const QString &column);
    //取指定select语句指定列名的值,该值是字节型
    QByteArray queryByteArrayValue(const QSqlQuery &query, const QString &column);

    QSqlDatabase db() const;

    QSqlQuery sqlQuery() const;

    void queryExec(QSqlQuery &query, bool &isSuccess, QString &errorText);
    void queryExec(QSqlQuery &query, const QString &sqlText, bool &isSuccess, QString &errorText);

我们操作数据库可以用上述方法就可以完成。

为了支持Qt对不同数据源及不同数据库操作,灵活配置在peanut_appconfig.xml中。

为了支持在代码层,SQL语句与代码业务逻辑不混在一起,支持它们之间的分离,支持不同数据库的切换,借鉴并简化了另一种方式SQLMapper,后面将重点介绍。

3.1. 配置项说明

DB模块的BeanConfig类名PlDBBeanConfig,该类目前实现的Bean类名PlDBController,结构如下:

BeanConfig:PlDBBeanConfig

    Bean:     PlDBController

PlDBBeanConfig配置项在peanut_appconfig.xml中,参考如下配置:

 <beanConfig id="dbBeanConfigSample" chooseBeanId="" className="peanut::PlDBBeanConfig"  name="DBModule" type="DB">
        <bean id="sqliteDBBeanSample" connectOptions="" userName="" port="" className="peanut::PlDBController" hostName=""  description="" isEncrypt="false" name="sqliteDBBeanSample" databaseName="./db/peanutsample.db" password="" type="QSQLITE">		 	
	  </bean>
 </beanConfig>

说明:

  1. BeanConfig: id="dbBeanConfigSample"的BeanConfig,对应的类名className="peanut::PlDBBeanConfig"
  2. Bean:在BeanConfig下配置一个id="sqliteDBBeanSample",类名className="peanut::PlDBController"

属性type:Qt的数据库驱动名称,有如下值可选,但是在Qt的版本中某些驱动要单独编译

QDB2        IBM DB2

QIBASE     Borland InterBase Driver

QMYSQL  MySQL Driver

QOCI        Oracle Call Interface Driver

QODBC    ODBC Driver (includes Microsoft SQL Server)

QPSQL     PostgreSQL Driver

QSQLITE   SQLite version 3 or above

QSQLITE2 SQLite version 2

QTDS        Sybase Adaptive Server

目前peanutlib1.5.10版本支持的驱动如下:

QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7

本例中配置的Bean的数据库驱动type=”QSQLITE”

属性name:name属性值在DB模块中具有唯一性,当Bean加载时,如果name值不存在,会将name的值使用QSqlDatabase::addDatabase(...)方法,如果name存在,会直接引用该数据库的QSqlDatabase对象。

属性databaseName数据库名称,对应QSqlDababase对象的setDatabaseName方法参数值。本例中,databaseName="./db/peanutsample.db",表示使用的sqlite数据库,它的数据库文件放在当前工作目录的db目录下的peanutsample.db文件中。

属性hostName主机名称,对应QSqlDababase对象的setHostName方法参数值。

属性userName用户名称,对应QSqlDababase对象的setUserName方法参数值。

属性password密码,对应QSqlDababase对象的setPassword方法参数值。

属性port端口号,对应QSqlDababase对象的sePort方法参数值。

属性isEncrypt是否当前Bean的数据库配置项加密保护(通常在系统上线运行后,可使用该开关将配置数据库的数据加密),true表示加密,设置后系统运行时会自动加密字符串;false表示不加密,使用当前配置项的值。

3.2 建立多数据源

多数据源指能得到一至多个数据库的连接,例如,得到一个连接sqlite的数据库连接,得到一个连接MYSQL的数据库连接,利用连接对象就可以对数据库操作(注:peanutlib的数据库连接与操作都由PlDBController完成)。下面是示例及运行界面。

  • 在peanut_appconfig.xml中设置DB模块 
      <beanConfig id="dbBeanConfigSample" name="DBModule" type="DB" className="peanut::PlDBBeanConfig" chooseBeanId="" >
        <bean id="sqliteDBBeanSample" name="sqliteDBBeanSample" className="peanut::PlDBController"  databaseName="./db/peanutsample.db"  type="QSQLITE" userName="" port="" hostName="" description="" isEncrypt="false"  password=""   connectOptions="" >		 	
	    </bean>
		<bean id="mysqlDBBeanSample" name="mysql-peanutsample"  className="peanut::PlDBController" hostName="127.0.0.1" userName="root" password="123456"  port="3306"  databaseName="peanutsample"  type="QMYSQL" isEncrypt="false" connectOptions="">
        </bean>
      </beanConfig>

注:id="dbBeanConfigSample"的DB模块,配置两个Bean,分别是id="sqliteDBBeanSample"的连接sqlite数据库(该数据库放在本地当前工作目录/db/peanutsample.db中),id="mysqlDBBeanSample"连接mysql数据库(本机安装mysql,建立名为peanutsample的数据库)。

  • .h文件ps_conndb_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_CONNDB_MAINWINDOW_H
#define PS_CONNDB_MAINWINDOW_H

#include <QMainWindow>
#include <pl_db.h>

#include <grid/pl_grid_info.h>

namespace peanut {

namespace Ui {
class PsConndbMainWindow;
}

class PsConndbMainWindow : public QMainWindow
{
    Q_OBJECT

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

protected:
    //初始化
    void init();
    //将Bean的属性值转换到TableWidget中
    void insertTableWidget(const PlBeanInfo &beanInfo, int row=0);
    //将Bean的属性值转换到表单界面中
    void setDBParamForm(const PlBeanInfo &beanInfo);
    //从界面中取已设定的参数值
    PlSequenceMap getMapFromDialog(bool &isSuccess, QString &errMsg);
private slots:
    //当前TableWidget的行发生改变后触发
    void on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous);

    //单击测试连接
    void on_tbTest_clicked();

private:
    Ui::PsConndbMainWindow *ui;

    //DB模块的BeanConfig对象
    PlDBBeanConfig     *m_dbBeanConfig=nullptr;
    //DB模块的BeanCoinfig的ID值
    QString             m_dbBeanConfigId="dbBeanConfigSample";
    //设置一个Grid对象(注:tableWidget 属于Grid)
    PlGridInfo          m_gridInfo;
    //图标颜色
    QColor   m_iconColor = QColor(Qt::red);
};

}


#endif // PS_CONNDB_MAINWINDOW_H

  • .cpp文件ps_conndb_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_conndb_mainwindow.h"
#include "ui_ps_conndb_mainwindow.h"

#include <pl_utils.h>

namespace peanut {

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

    bool isSuccess;
    QString errMsg;

    //设置测试连接的图标
    QVariantMap options;
    options.insert( "color" , m_iconColor);
    QIcon icon = PlQIconUtils::getIcon("repeat", isSuccess, errMsg, options);
    ui->tbTest->setIcon(icon);

    //设置连接类型的初始值
    ui->cbType->clear();
    QStringList list = QSqlDatabase::drivers();
    foreach(QString type, list) {
        ui->cbType->addItem(type);
    }

    //初始化
    init();
}

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

void PsConndbMainWindow::init()
{
    PsApplication *app = PsApplication::getPsApplication();
    Q_ASSERT(app!=nullptr);

    //得到DB模块的BeanConfig对象
    m_dbBeanConfig = app->getDBBeanConfig(m_dbBeanConfigId);
    if(m_dbBeanConfig==nullptr) {
        PlMessageBox::warning(this, tr("异常警告信息"), tr("找不到[id=%1]的DBBeanConfig").arg(m_dbBeanConfigId));
        return;
    }

    //设置Grid的表格头
    m_gridInfo.insertHearderColumnInfo(PlGridHearderColumnInfo("beanId", tr("连接Id"), Qt::Horizontal));
    m_gridInfo.insertHearderColumnInfo(PlGridHearderColumnInfo("beanName", tr("连接名称"), Qt::Horizontal));
    m_gridInfo.insertHearderColumnInfo(PlGridHearderColumnInfo("beanType", tr("连接类型"), Qt::Horizontal));
    m_gridInfo.insertHearderColumnInfo(PlGridHearderColumnInfo("beanConfigId", tr("配置项Id"), Qt::Horizontal));
    m_gridInfo.insertHearderColumnInfo(PlGridHearderColumnInfo("beanConfigName", tr("配置项名称"), Qt::Horizontal));

    //初始化TableWidget的表格头
    ui->tableWidget->setColumnCount(m_gridInfo.countColumn());
    foreach(PlGridHearderColumnInfo info, m_gridInfo.getHearderColumnInfos()) {
        QTableWidgetItem  *headerItem = new QTableWidgetItem();
        headerItem->setText(info.getColumnValue());
        QFont font = headerItem->font();  //获取原有字体设置
        font.setBold(true);//设置为粗体
        headerItem->setFont(font);//设置字体
        headerItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        ui->tableWidget->setHorizontalHeaderItem(info.getColumnNo(), headerItem); //设置表头单元格的Item
    }

    //得到DB模块的BeanConfig的Info对象
    PlBeanConfigInfo beanConfig = m_dbBeanConfig->getBeanConfigInfo();
    //取DB模块的BeanConfig的所有Bean的Info对象
    QList<PlBeanInfo> beanList =  beanConfig.getBeanInfos();
    int curRow = 0;
    foreach(PlBeanInfo info, beanList) {
        if(info.type()=="SQLMapper") {
            continue;
        }
        curRow = ui->tableWidget->rowCount();
        if(curRow<0) curRow = 0;
        ui->tableWidget->insertRow(curRow);

        //将当前Bean的Info对象转换到TableWidget中
        insertTableWidget(info, curRow);
    }
    ui->tableWidget->setSelectionBehavior( QAbstractItemView::SelectionBehavior::SelectRows );
    ui->tableWidget->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
    ui->tableWidget->setAlternatingRowColors(true);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);

    //绑定tableWidget对象的当前行发生改变信号与槽
    connect(ui->tableWidget->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
                this,SLOT(on_currentRowChanged(QModelIndex,QModelIndex)));

    if(ui->tableWidget->rowCount()>0) {
        QTableWidgetItem *item = ui->tableWidget->item(0,0);
        ui->tableWidget->setCurrentItem(item);  //第一行为当前行
    }
}

void PsConndbMainWindow::insertTableWidget(const PlBeanInfo &beanInfo, int row)
{
    Q_ASSERT(m_dbBeanConfig!=nullptr);

    QTableWidgetItem *item = new QTableWidgetItem();
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));//设置不可编辑
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setText(beanInfo.id());
    ui->tableWidget->setItem(row, 0, item);

    item = new QTableWidgetItem();
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));//设置不可编辑
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setText(beanInfo.name());
    ui->tableWidget->setItem(row, 1, item);

    item = new QTableWidgetItem();
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));//设置不可编辑
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setText(beanInfo.type());
    ui->tableWidget->setItem(row, 2, item);

    item = new QTableWidgetItem();
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));//设置不可编辑
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setText(m_dbBeanConfig->getBeanConfigInfo().id());
    ui->tableWidget->setItem(row, 3, item);

    item = new QTableWidgetItem();
    item->setFlags(item->flags() & (~Qt::ItemIsEditable));//设置不可编辑
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    item->setText(m_dbBeanConfig->getBeanConfigInfo().name());
    ui->tableWidget->setItem(row, 4, item);
}

void PsConndbMainWindow::setDBParamForm(const PlBeanInfo &beanInfo)
{
    //得到Bean的Info对象的所有属性与值
    QMap<QString,QString> map = beanInfo.attrMap();

    QString isEncrypt = map.value("isEncrypt","");
    if(isEncrypt.toLower()!="true") {
        isEncrypt = "false";
    }
    else {
        isEncrypt = "true";
    }
    QString value;
    if(isEncrypt=="true") {
        value = map.value("hostName");
        value = PlBaseDBController::decrypt(value);
        map.insert("hostName", value);

        value = map.value("userName");
        value = PlBaseDBController::decrypt(value);
        map.insert("userName", value);

        value = map.value("password");
        value = PlBaseDBController::decrypt(value);
        map.insert("password", value);

        value = map.value("port");
        value = PlBaseDBController::decrypt(value);
        map.insert("port", value);

        value = map.value("databaseName");
        value = PlBaseDBController::decrypt(value);
        map.insert("databaseName", value);
    }
    ui->leId->setText(beanInfo.id());
    ui->leName->setText(beanInfo.name());
    ui->leUserName->setText(map.value("userName"));
    ui->leIP->setText(map.value("hostName"));
    ui->lePassword->setText(map.value("password"));
    ui->lePort->setText(map.value("port"));
    ui->leDatabaseName->setText(map.value("databaseName"));
    ui->leConnectOptions->setText(map.value("connectOptions"));
    if(isEncrypt=="true") {
        ui->rbIsEncryptY->setChecked(true);
        ui->rbIsEncryptN->setChecked(false);
    }
    else {
        ui->rbIsEncryptY->setChecked(false);
        ui->rbIsEncryptN->setChecked(true);
    }
    value = map.value("type");
    ui->cbType->setCurrentText(value);
}

PlSequenceMap PsConndbMainWindow::getMapFromDialog(bool &isSuccess, QString &errMsg)
{
    PlSequenceMap map;  //按先进序列排序的Map
    PlCheckInputStateForm input;  //检查界面中输入型控件的状态
    try {
        input.inputTextAndIsNull(ui->leId, "id", tr("输入框[%1]不能为空").arg("连接ID"),true);
        input.inputTextAndIsNull(ui->leName, "name", tr("输入框[%1]不能为空").arg("连接名称"),true);
        input.inputTextAndIsNull(ui->leIP, "hostName", "", false);
        input.inputTextAndIsNull(ui->leUserName, "userName", "",true);
        input.inputTextAndIsNull(ui->lePassword, "password", "",true);
        input.inputTextAndIsNull(ui->lePort, "port", "",true);
        input.inputTextAndIsNull(ui->leDatabaseName, "databaseName", "",true);
        input.inputTextAndIsNull(ui->leConnectOptions, "connectOptions", "",true);
        input.inputTextAndIsNull(ui->cbType, "type", "",true,false);

        if(ui->rbIsEncryptY->isChecked()) {
            input.inputValue("isEncrypt", "true");
        }
        else {
            input.inputValue("isEncrypt", "false");
        }

        input.inputValue("className", "peanut::PlDBController");
    } catch (PeanutError err) {
        isSuccess = false;
        errMsg = err.what();
        return PlSequenceMap();
    }
    isSuccess = true;
    return input.sequenceMap();
}

void PsConndbMainWindow::on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous);
    if (!current.isValid())
    {
        return;
    }
    ui->leId->setReadOnly(true);
    //得到当前tableWidget的Id列值
    QString beanId = ui->tableWidget->item(current.row(), 0)->text();
    //得到DB模块BeanConfig对象
    PlBeanConfigInfo beanConfig = m_dbBeanConfig->getBeanConfigInfo();
    QList<PlBeanInfo> beanList =  beanConfig.getBeanInfos();
    //遍历BeanConfig对象所有Bean
    foreach(PlBeanInfo info, beanList) {
        if(info.type()=="SQLMapper") {
            continue;
        }
        //如果当前tableWidget的Id等于Bean的ID
        if(info.id()==beanId) {
            //将Bean的Info转换到界面中
            setDBParamForm(info);
            break;
        }
    }
}

void peanut::PsConndbMainWindow::on_tbTest_clicked()
{
    Q_ASSERT(m_dbBeanConfig!=nullptr);
    bool isSuccess;
    QString errMsg;
    try {
        //得到当前界面的参数值
        PlSequenceMap seqMap = getMapFromDialog(isSuccess, errMsg);
        if(!isSuccess) {
            throw PeanutError(errMsg);
        }
        //转换成QMap
        QMap<QString,QString> map = seqMap.toMap();
        //使用参数值集创建一个PlDBController对象
        PlDBController dbCtrl(map);
        QString name = map.value("name");
        //打开并连接数据库
        isSuccess = dbCtrl.open();
        //如果打开失败,拋出异常
        if(!isSuccess) {
            throw PeanutError(dbCtrl.lastError());
        }
        //关闭数据库
        dbCtrl.close();
        PlMessageBox::information(this, tr("信息提示"), tr("连接[%1]成功").arg(name),QMessageBox::Ok);
    } catch (PeanutError err) {
        PlMessageBox::warning(this, tr("异常警告信息"), err.what());
    }
}

}

  • .ui文件ps_conndb_mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>peanut::PsConndbMainWindow</class>
 <widget class="QMainWindow" name="peanut::PsConndbMainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>DB模块-多数据库连接</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QToolButton" name="tbTest">
        <property name="toolTip">
         <string>测试当前连接是否正常</string>
        </property>
        <property name="text">
         <string>测试连接</string>
        </property>
        <property name="toolButtonStyle">
         <enum>Qt::ToolButtonTextUnderIcon</enum>
        </property>
       </widget>
      </item>
      <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>
     </layout>
    </item>
    <item>
     <widget class="QSplitter" name="splitter">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>7</verstretch>
       </sizepolicy>
      </property>
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="QTableWidget" name="tableWidget">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>4</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
      </widget>
      <widget class="QGroupBox" name="groupBox">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
         <horstretch>6</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="title">
        <string/>
       </property>
       <layout class="QGridLayout" name="gridLayout">
        <item row="9" column="1">
         <widget class="QLabel" name="label_9">
          <property name="text">
           <string>是否存储加密:</string>
          </property>
         </widget>
        </item>
        <item row="4" column="2">
         <widget class="QLineEdit" name="lePort"/>
        </item>
        <item row="7" column="1">
         <widget class="QLabel" name="label_8">
          <property name="text">
           <string>数据库名称(databaseName):</string>
          </property>
         </widget>
        </item>
        <item row="10" column="2">
         <widget class="QRadioButton" name="rbIsEncryptN">
          <property name="text">
           <string>否</string>
          </property>
         </widget>
        </item>
        <item row="6" column="2">
         <widget class="QLineEdit" name="lePassword">
          <property name="echoMode">
           <enum>QLineEdit::Password</enum>
          </property>
         </widget>
        </item>
        <item row="6" column="1">
         <widget class="QLabel" name="label_6">
          <property name="text">
           <string>用户密码(password):</string>
          </property>
         </widget>
        </item>
        <item row="5" column="1">
         <widget class="QLabel" name="label_5">
          <property name="text">
           <string>用户名称(userName):</string>
          </property>
         </widget>
        </item>
        <item row="7" column="2">
         <widget class="QLineEdit" name="leDatabaseName"/>
        </item>
        <item row="9" column="2">
         <widget class="QRadioButton" name="rbIsEncryptY">
          <property name="text">
           <string>是</string>
          </property>
          <property name="checked">
           <bool>true</bool>
          </property>
         </widget>
        </item>
        <item row="0" column="2">
         <widget class="QLineEdit" name="leId">
          <property name="minimumSize">
           <size>
            <width>200</width>
            <height>0</height>
           </size>
          </property>
         </widget>
        </item>
        <item row="1" column="1">
         <widget class="QLabel" name="label_2">
          <property name="text">
           <string>连接名称:</string>
          </property>
         </widget>
        </item>
        <item row="3" column="1">
         <widget class="QLabel" name="label_4">
          <property name="text">
           <string>服务器地址(hostName):</string>
          </property>
         </widget>
        </item>
        <item row="5" column="2">
         <widget class="QLineEdit" name="leUserName"/>
        </item>
        <item row="0" column="1">
         <widget class="QLabel" name="label">
          <property name="text">
           <string>连接ID:</string>
          </property>
         </widget>
        </item>
        <item row="4" column="1">
         <widget class="QLabel" name="label_7">
          <property name="text">
           <string>端口号(port):</string>
          </property>
         </widget>
        </item>
        <item row="2" column="1">
         <widget class="QLabel" name="label_3">
          <property name="text">
           <string>连接类型:</string>
          </property>
         </widget>
        </item>
        <item row="2" column="2">
         <widget class="QComboBox" name="cbType"/>
        </item>
        <item row="1" column="2">
         <widget class="QLineEdit" name="leName"/>
        </item>
        <item row="3" column="2">
         <widget class="QLineEdit" name="leIP"/>
        </item>
        <item row="8" column="1">
         <widget class="QLabel" name="label_10">
          <property name="text">
           <string>连接选项(connectOptions):</string>
          </property>
         </widget>
        </item>
        <item row="8" column="2">
         <widget class="QLineEdit" name="leConnectOptions"/>
        </item>
       </layout>
      </widget>
     </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>

4. 代码下载

代码下载链接:https://pan.baidu.com/s/1VMrSKbQq6xL_haLPw3qVeg?pwd=zmp3 提取码: zmp3

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、付费专栏及课程。

余额充值