baizy77 发表于 2018-11-3 12:05:45

【独家连载】Qt入门与提高 KS04-11 编写自己的公共类库

本帖最后由 baizy77 于 2019-7-2 20:35 编辑

版权声明---------------------------------------------------------------------------------------------------------------------该文章原创于Qter开源社区(www.qter.org)作者: 女儿叫老白转载请注明出处!---------------------------------------------------------------------------------------------------------------------课程目录: 【独家连载】《Qt入门与提高-GUI产品开发》目录
网页版课程源码 提取码:1uy7
引言----------------------------------------------------------------------------------------------------------------------在前面的章节中,我们介绍了如何开发一个dll模块。在项目或者产品开发过程中,我们经常会开发一些公共的dll模块用来实现一些基础功能,比如路径解析、svg中的颜色值与QColor互相转换等。今天我们为大家简单介绍一下如何开发公共类库。
正文----------------------------------------------------------------------------------------------------------------------开发dll的技术在前面章节已经详细介绍过,因此本节的重点是给大家举例介绍抽取公共类或接口组成公共类库,也算是对dll开发技术的一次练兵。    本节给出的示例代码中,给出了如下接口:
namespace ns_train {
    // == 颜色相关 =============================================================================
    /**
    * @brief 解析颜色, 将字符串转换为QColor.
             格式:r,g,b[,a], alpha可选
    * @param strColor待解析的字符串
    * @return 解析所得的颜色
    */
    KS04_11_Export QColor parseColor(const QString& strColor);

    /**
    * @brief 将QColor格式化未字符串,输出的格式:r,g,b,a
    * @param clr待转换的颜色
    * @return 解析所得的颜色字符串
    */
    KS04_11_Export QString getColorRgbValue(const QColor& clr);

    // == 文件相关 =============================================================================
    /**
    * @brief 获取指定path的字符串, 如果使用环境变量,格式必须为:"$环境变量名/xxx/xxx"
             接口内部负责:
             1. 将"\\"转换为"/"
             2. 自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如, 输入:"$TRAINDEVHOME/src",输出:"d:/xingdianketang/project/gui/src/"

    * @param strPath 指定路径
    * @return 文件名, 全路径
    */
    KS04_11_Export QString getPath(const QString& strPath);

    /**
    * @brief 获取指定path所在的全目录名, 如果使用环境变量,格式必须为:"$环境变量名/xxx/xxx.yy"
             接口内部负责:
             1. 将"\\"转换为"/"
             2. 自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如, 输入:"$TRAINDEVHOME/src/a.txt",输出:"d:/xingdianketang/project/gui/src/"
    * @param strPath 指定路径
    * @return 文件名所在目录
    */
KS04_11_Export QString getDirectory(const QString& strPath);

    /**
    * @brief 获取指定文件名的名称,如果使用环境变量,格式必须为:"$环境变量名/xxx/xxx.yy"
             接口内部负责:
             1. 将"\\"转换为"/"
             2. 自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如, 输入:"$TRAINDEVHOME/src/a.txt",输出:"a.txt"
    * @param strFilePath 指定文件(全路径)
    * @return 文件名(a.txt)
    */
    KS04_11_Export QString getFileName(const QString& strFilePath);

      /**
* @brief 获取指定strDirectory的当前子目录名, 如果使用环境变量,格式必须为:"$环境变量名/xxx/xxx/xxx/"
          接口内部负责:
          1. 将"\\"转换为"/"
2. 自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如, 输入:"$TRAINDEVHOME/src/exchange",输出:"exchange"
      * @param strDirectory 指定路径
      * @return 当前子目录名
      */
      KS04_11_Export QString getNameOfDirectory(const QString& strDirectory);

    /**
    * @brief 获取指定目录下的所有文件名
    * @param strPath 指定路径,内部会将"\\"转换为"/"
    * @param nameFilters 文件名过滤符,比如:"*.h"
    * @param bRecursive true:递归. false:仅根目录
    * @return 文件名列表, 全路径
    */
    KS04_11_Export QStringList getFileList(const QString& strPath, const QStringList& nameFilters, bool bRecursive);
      /**
* @brief 获取指定文件对于指定目录的相对路径, 比如,"d:/temp/file/a.txt",相 对于 "d:/temp/"的相对路径为"/file/a.txt"。
      * @param strFileName 指定文件(带绝对路径)
      * @param strDirectory 指定路径(带绝对路径),可以不带最后的“/”。
      * @return 相对路径
      */
      KS04_11_Export QString getReleativePath(const QString& strFileName, const QString& strDirectory);
      /**
      * @brief 获取指定文件的md5码。
      * @param strFileName 指定文件(带绝对路径)
      * @return md5码
      */
      KS04_11_Export QByteArray getMd5(const QString& strFileName);
}
    可以看出,我们给出的示例中,使用了命名空间。我们建议:在提供公共类库时,要使用命名空间,以便解决命名冲突的问题。在我们的示例程序接口中,有颜色转换的接口、有路径解析的接口、有处理md5码的接口等等。这些都是一些基础的、公共的功能。抽取基础的、公共的功能模块是我们建立公共类库的原则。我们以下面两个接口为例,给大家做一下介绍:QString getPath(const QString& strPath);
QStringList getFileList(const QString& strPath, const QStringList& nameFilters, bool bRecursive);
我们分别来看一下:l 示例接口1,getPath ():    /**
    * @brief 获取指定path的字符串, 如果使用环境变量,格式必须为:"$环境变量名\xxx\xxx"
             接口内部负责:
             1. 将"\\"转换为"/"
             2. 自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如, 输入:"$TRAINDEVHOME/src",输出:"d:/xingdianketang/project/gui/src/"
    * @param strPath 指定路径
    * @return 文件名, 全路径
    */
    KS04_11_Export QString getPath(const QString& strPath);
这个接口用来解析指定路径的字符串, 如果使用环境变量,格式必须为:"$环境变量名\xxx\xxx"。接口内部将windows风格的目录分隔符"\"转换为linux风格的"/"。自动将环境变量替换为实际路径,环境变量使用$XXX的格式,比如,输入:"$TRAINDEVHOME/src",输出:"d:/xingdianketang/project/gui/src/"l 调用该接口的示例代码如下:/**
* @brief 示例1, 介绍QDir的使用
* @return void
*/
void example02(void) {
    QString strPath = "$TRAINDEVHOME/src";
    strPath = ns_train::getPath(strPath);
    QDir dir(strPath);
    QString absPath = dir.absolutePath();
    QString cancPath =dir.canonicalPath();
}
请注意上述代码中的dir.absolutePath()和dir.canonicalPath(),请读者实际测试一下,看看有什么不同。l 示例接口2,getFileList():/**
    * @brief 获取指定目录下的所有文件名
    * @param strPath 指定路径,内部会将"\\"转换为"/"。支持环境变量,比如"$TRAINDEVHOME\temp"
    * @param nameFilters 文件名过滤符,比如:"*.h"
    * @param bRecursive true:递归. false:仅根目录
    * @return 文件名列表, 全路径
    */
    KS04_11_Export QStringList getFileList(const QString& strPath, const QStringList& nameFilters, bool bRecursive);
这个接口用来获取指定目录下的所有文件。支持递归。接口内部将windows风格的目录分隔符"\"转换为linux风格的"/"。支持文件名过滤。支持环境变量,比如"$TRAINDEVHOME\temp"。 可以看出,这些接口在设计时对于跨平台特性和易用性都考虑到了。    调用该接口的示例代码如下:/**
* @brief example01, 调用dll中的接口
* @return void
*/
void example01(void) {
    QString strPath = "d:\\temp_D";
    QStringList strFilters;
strFilters << "*.gdf" << "*.xml";   
QStringList strList = ns_train::getFileList(strPath, strFilters, true);
}
请注意文件名过滤字符串的写法:    strFilters << "*.gdf"<< "*.xml";上述语句表示搜索所有的"*.gdf"文件和"*.xml"文件。上面我们简要介绍了公共类库示例代码中的两个例子,其他几个例子的设计原则类似,我们不再展开,大家可以自行查阅附件代码。结语----------------------------------------------------------------------------------------------------------------------在设计公共类库时,我们需要把握如下的原则:    1. 公共类库包含的是公用的、基础功能模块。    2. 要考虑跨平台特性,比如:字节序、大小端、目录分隔符、目录(文件)名大小写等。    3. 要考虑易用性。设计时要从使用者的角度而非实现的角度思考问题。    公共类库在项目、产品开发过程中有着非常重要的地位。如果能提供一个非常好用的公共类库,对于软件研发组织来说,不论是提高效率、降低成本、还是提升代码稳定性都能起到非常重要的作用。----------------------------------------------------------------------------------------------------------------------上一节 KS04-07   常用Qt类-QMap下一节 KS04-09   普通文本文件读写


liudianwu 发表于 2018-12-1 09:11:28

讲得非常好!尤其是这点:要考虑易用性。设计时要从使用者的角度而非实现的角度思考问题。

xinjian185 发表于 2018-12-3 18:20:46

老大能详细解释一个库吗

baizy77 发表于 2018-12-4 08:24:40

本帖最后由 baizy77 于 2018-12-4 08:52 编辑

xinjian185 发表于 2018-12-3 18:20
老大能详细解释一个库吗
您好,本节的重点是介绍类库的设计原则,侧重接口设计而非接口实现,因此源码不作为重点,如果您对源码感兴趣,可以关注视频课程。

baizy77 发表于 2019-9-6 14:09:48

xinjian185 发表于 2018-12-3 18:20
**** 作者被禁止或删除 内容自动屏蔽 ****

这位朋友,网页版源码已可下载,请在课程目录页获取下载地址。
页: [1]
查看完整版本: 【独家连载】Qt入门与提高 KS04-11 编写自己的公共类库