C++库,为什么选择Qt?

目录

一、Qt 是什么

二、Qt 历史

三、 Qt 授权

四、Qt适用领域       

五、C++的标准库

六、为什么选Qt

1、获取当前时间的毫秒数

2、字符串劈开

3、忽略大小写的字符串比较


一、Qt 是什么

  • 是一个C++的第三方开发库,含开发用户界面的组件库;
  • 是一个跨平台的库,兼容Windows、Linux、Mac等系统。

二、Qt 历史

Qt库历史悠久,超过30年的发展历史。经历曲折,跌宕起伏。至今仍然生机勃勃。

Qt 库最初由芬兰公司 Trolltech 开发,后来被瑞典公司 Digia 收购。Qt 最早是作为一个用于开发图形用户界面(GUI)的工具包出现的,但后来发展为一个跨平台的应用开发框架,提供了一系列的工具和类来帮助开发人员开发应用程序。现在,Qt 库在各种平台上都得到广泛使用,包括 Linux、Windows、macOS 和 Android。

时间主角事件
1991年挪威的 Eirik Chambe-Eng 和 Haavard Nord初创开发的库
1994年3月挪威的 Eirik Chambe-Eng 和 Haavard Nord成立奇趣科技公司(Trolltech)、商业授权
2000年奇趣科技公司发布 GPL(GNU General Public License)许可证的开源版本Qt
2008年诺基亚和奇趣科技公司诺基亚公司收购了奇趣科技公司、增加了 LGPL(GNU Lesser General Public License)的授权模式
2011年3月芬兰IT服务公司 DigiaQt 商业授权业务出售给了芬兰IT服务公司 Digia
2014年9月Digia宣布成立 Qt Company 全资子公司独立运营 Qt 商业授权业务。目前 Qt 公司大力推广移动平台开发和商业应用

三、Qt 授权

它提供了两种授权方式:商业授权和开源授权。LGPL 和 GPL 是免费发布,商业版则需收取授权费。

  • Qt 商业版授权适用于开发专属和/或商业软件。这个版本适合那些不希望与他人共享源代码,或者遵循 GNU LGPL 2.1 或 GNU GPL 3.0 版本条款的开发人员。它提供了技术支持服务,允许开发人员修改 Qt 的源代码,而无需公开。

    Qt 4.5.0 及更高版本遵循 GNU LGPL。LGPL 允许任何许可证的软件链接到它,并允许专属软件作为类库引用、发布和销售。您可以购买支持服务。

    如果您希望将 Qt 应用程序与遵循 GNU GPL 3.0 版本条款的软件一起使用,或者您希望 Qt 应用程序遵循该许可证的条款,则这个版本的 Qt 库适合开发这类应用程序。您也可以购买支持服务。

四、Qt适用领域       

        Qt适用开发桌面程序、移动端的App。另外,Qt可以网站服务器开发吗?从技术上来说,是可以的,但是有更多更好的技术可选择,不推荐用Qt开发服务器端。


五、C++的标准库

        首选C++是有官方标准库的。但是标准库并不友好,使用过程中存在类似以下的感受:

  • 功能不够完善,比如字符串string类没有劈开字符串的方法、没有string转wstring的方法,没有trim方法、没有忽略字符串大小写比较的方法等等。而这些在日常的开发中,经常用到,如果没有,你得自己去实现或者找一个其他的库;
  • 功能接口的调用过于繁琐,往往望而生畏的感觉。
  • 也许对于不同的人还有不同的感受,比如方法名有很多下划线,看起来眼花缭乱。

       对C++标准库的感受,这里不一一列举。毕竟,不同人感受不同。如果您的项目必须要用C++的标准库,也是可以的,Google的Chrome就是大量使用标准库,并且还拓展了标准库,把拓展的部分开源出来供大家使用。所以,如果项目必须使用标准库,可以考虑使用Google的开源C++库:Abseil 作为补充。

        除了标准库,C++还有一些类似标准库的第三方库,举例子如下:

库名简介
Boost

C++标准委员会库工作组成员发起,在C++社区中影响甚大,其成员已近2000人。   
Boost库为我们带来了最新、最酷、最实用的技术,是不折不扣的“准”标准库。

但是没有提供图像界面的开发库。

这个库非常庞大,有很多子库,子库目录非常值得去浏览一遍。说不定哪天还真的用得上。

Qt

就是本文的主角了。在我看来,如果Qt作为C++官方标准库,那么C++将会像Java一样完善好用。

Qt的子库非常多,很多Boost里面有的库,在Qt也有类似的库或功能。并且还提供完善的跨平台的图像界面库。

Qt的类、方法设计也是下足了心思,让开发者使用起来非常舒服。下面会讲到它的优点。

JUCEJUCE (Jules' Utility Class Extensions)是由Raw MaterialSoftware发布的一套基于c++的跨平台应用程序框架类库(Windows, Mac,Linux)。JUCE的特殊之处在于其友好的用户界面以及强大的音频、图像处理能力。JUCE适合那些想使用干净、快捷、高层的API,而不想 把时间浪费在使用不同类库,面向不同平台上的开发者。JUCE能够胜任大型、复杂的应用程序(C++)的开发。

        能够担当标准库的第三方库,确实不多,想进一步挖掘更多库的读者,可以到百度、Google等引擎去搜索和了解。

六、为什么选Qt

类比Java, 就会非常明显感受到Java的官方标准库非常完善,涉及到日常软件开发的方方面面。既可以开发桌面程序也可以开发网站。并且有活跃的开源社区,数量庞大的开源项目,成熟完善的工具链。让Java开发工程师如鱼得水。

但这里讲的是C++,咱C++木有这样的官方库。而Qt库相比其他的库,拥有完善的基础类库和图形界面库,并且拥有跨平台特性,更像是大多数应用软件开发者所期望的C++标准库。

Qt的核心能力在于基础类库、用户图形界面库、跨平台特性。除此之外,它的开源、库完整性、稳定性、易用性、代码美观程度、完善的帮助文档、搜索引擎可查到的资料、免费商用、与时俱进的版本更新等等,都在为它加分。

作为直观对比,拿Qt、C++标准库、Boost来实现几个小逻辑,这些小逻辑可能在开发日常经常用到,视不同项目而不同:

1、获取当前时间的毫秒数

C++标准库

#include <chrono>
using namespace std;

long long getCurrentMillisecond(){    
    auto time_now = chrono::system_clock::now();
	auto duration_in_ms = chrono::duration_cast<chrono::milliseconds>(time_now.time_since_epoch());
	return duration_in_ms.count();
}

Boost 库

#include <boost/date_time/posix_time/posix_time.hpp>  
#include <boost/date_time/gregorian/gregorian.hpp>  
using namespace boost::posix_time;
using namespace boost::gregorian;

long long getCurrentMillisecond(){
    ptime epoch(date(1970, boost::gregorian::Jan, 1));
    time_duration time_from_epoch = second_clock::universal_time() - epoch;
    return time_from_epoch.total_milliseconds();
}

Qt库

#include <QDateTime>

long long getCurrentMillisecond(){
    return QDateTime::currentMSecsSinceEpoch();
}

单从代码行数,心智负担来看,Qt库的实现,是比较人性化的。它单纯提供一个方法来完成该逻辑。

2、字符串劈开

给定一个字符串“Leander#GuangDong#100”,需要劈开该字符串到一个数组或者字符串列表均可。

C++标准库

不支持该方法,需要自行实现。经过一番折腾,实现如下

#include <string>
#include <sstream>
#include <vector>
using namespace std;

vector<string> split(const string &s, char delim) {
  stringstream ss(s);
  string item;
  vector<string> elems;
  while (getline(ss, item, delim)) {
    elems.push_back(item);
  }
  return elems;
}

Boost 库

#include <string>
#include <vector>
using namespace std;
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

vector<string> split(const string &s, char delim) {
    vector<string> elems;
    boost::split(elems, s, boost::is_any_of(delim));
    return elems;
}

Qt库

#include <QString>
#include <QStringList>

QStringList split(const QString &s, char delim) {
    return s.split(delim, QString::SkipEmptyParts);
}

除此之外,QString还提供9个split的方法,方便您随意劈,如下:

普通的使用场景下:

 QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

 QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

 QStringList split(const QRegExp &rx, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;

 QStringList split(const QRegularExpression &re, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;

在性能要求苛刻的场景下:

 QVector<QStringRef> splitRef(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

 QVector<QStringRef> splitRef(QChar sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

 QVector<QStringRef> splitRef(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

 QVector<QStringRef> splitRef(const QRegExp &rx, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;

 QVector<QStringRef> splitRef(const QRegularExpression &re, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const

3、忽略大小写的字符串比较

C++标准库

#include <algorithm>
#include <cctype>
#include <cstring>
#include <iostream>
using namespace std;

bool iequals(const std::string& str1Input, const std::string& str2Input)
{
    string str1 = str1Input;
    string str2 = str2Input;
    transform(str1.begin(), str1.end(), str1.begin(), ::toupper);
    transform(str2.begin(), str2.end(), str2.begin(), ::toupper);
    return strcmp(str1.c_str(), str2.c_str()) == 0 ? true : false;
}

Boost库

#include <boost/algorithm/string.hpp>
#include <string>

bool iequals(const std::string& str1Input, const std::string& str2Input)
{
    return boost::iequals(str1, str2); 
}

Qt库

#include <QString>

bool iequals(const QString& str1Input, const QString& str2Input)
{
    return str1Input.compare(str2Input, Qt::CaseInsensitive) == 0; // equal will be true
}

更多的就不一一列举,读者可自行去了解更多。从上面的几个例子,可以明显感受到:C++标准库的使用体验是最槽糕的,boost好一些,Qt感觉良好。

在此建议,选择好的库,就像选择好的伙伴一样重要。一路开发下来,会顺畅很多,后期发布运行也更稳定。


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值