Qt 4开发实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第3章 Qt的模板库、工具类及控件

本章首先介绍Qt字符串类QString、Qt容器类、QVariant类以及Qt常用的算法和基本正则表达式,最后概括介绍常用的控件名称及其用法。

3.1 字符串类QString

标准C++提供了两种字符串:一是C风格的以“\0”字符结尾的字符数组,二是字符串类String。而Qt字符串类QString功能更强大。

QString类保存16位Unicode值,提供了丰富的操作、查询、转换等函数。该类还进行了使用隐式共享(implicit sharing)、高效的内存分配策略等多方面的优化。

3.1.1 操作字符串

字符串有几个操作符。

(1) QString提供了一个二元的“+”操作符组合两个字符串,并提供了一个“+=”操作符将一个字符串追加到另一个字符串的末尾,例如:

        QString str1 = "Welcome ";
        str1=str1+"to you! ";       //str1=" Welcome to you! "
        QString str2="Hello, ";
        str2+="World! ";           //str2="Hello,World! "

其中,QString str1 = "Welcome"传递给QString一个const char*类型的ASCII字符串“Welcome”,它被解释为一个典型的以“\0”结尾的C类型字符串。这将会导致调用QString构造函数,来初始化一个QString字符串。其构造函数原型为:

        QT_ASCII_CAST_WARN_CONSTRUCTOR QString::QString(const char* str)

被传递的const char*类型的指针又将被函数QString::fromAscii()转换为Unicode编码。默认情况下,函数QString::fromAscii()会把超过128的字符作为Latin-1进行处理(可以通过调用QTextCodec::setCodecForCString()函数改变QString::fromAscii()函数的处理方式)。

此外,在编译应用程序的时候,也可以通过定义QT_CAST_FROM_ASCII宏变量屏蔽掉该构造函数。如果程序员要求显示给用户的字符串都必须经过QObject::tr()函数的处理,那么屏蔽掉QString的这个构造函数是非常有用的。

(2) QString::append()函数具有和“+=”操作符一样的功能,实现在一个字符串的末尾追加另一个字符串,例如:

        QString str1 = "Welcome ";
        QString str2 = "to ";
        str1.append(str2);        //str1=" Welcome to"
        str1.append("you! ");     //str1="Welcome to you! "

(3) 组合字符串的另一个函数是QString::sprintf(),此函数支持的格式定义符和C++库中的函数sprintf()定义的一样。例如:

        QString str;
        str.sprintf("%s"," Welcome ");                  //str="Welcome "
        str.sprintf("%s"," to you! ");                  //str="to you! "
        str.sprintf("%s %s"," Welcome ", "to you! ");   //str=" Welcome to you! "

(4) Qt还提供了另一种方便的字符串组合方式,使用QString::arg()函数,此函数的重载可以处理很多的数据类型。此外,一些重载具有额外的参数对字段的宽度、数字基数或者浮点数精度进行控制。通常,相对于函数QString::sprintf(),函数QString::arg()是一个比较好的解决方案,因为它类型安全,完全支持Unicode,并且允许改变"%n"参数的顺序。例如:

        QString str;
        str=QString("%1 was born in %2.").arg("John").arg(1982);//str="John was born in 1982."

其中:

● "%1"被替换为"John"

● "%2"被替换为"1982"

(5) QString也提供了一些其他组合字符串的方法,包括:

① insert()函数:在原字符串特定的位置插入另一个字符串;

② prepend()函数:在原字符串的开头插入另一个字符串;

③ replace()函数:用指定的字符串代替原字符串中的某些字符,等等。

(6) 很多时候去掉一个字符串两端的空白(空白字符包括回车字符“\n”,换行字符“\r”,制表符"\t"和空格字符" "等)非常有用,比如获取用户输入的账号时。

① QString::trimmed()函数:移除字符串两端的空白字符;

② QString::simplified()函数:移除字符串两端的空白字符,使用单个空格字符" "代替字符串中出现的空白字符。

例如:

        QString str="  Welcome \t to \n you!    ";
        str=str.trimmed();                        //str=" Welcome \t to \n you! "

在上述代码中,如果使用str=str.simplified(),则str的结果是“Welcome to you!”。

3.1.2 查询字符串数据

查询字符串数据有多种方式。具体如下:

(1) 函数QString::startsWith()判断一个字符串是否以某个字符串开头。此函数具有两个参数,第一个参数指定了一个字符串,第二个参数指定是否大小写敏感(默认情况下,是大小写敏感的),例如:

        QString str="Welcome to you! ";
        str.startsWith("Welcome",Qt::CaseSensitive);   //返回true;
        str.startsWith("you",Qt::CaseSensitive);       //返回false;

(2) 类似于函数QString::startsWith(),此函数判断一个字符串是否以某个字符串结尾。

(3) 函数QString::contains()判断一个指定的字符串是否出现过,例如:

        QString str=" Welcome to you! ";
        str.contains("Welcome",Qt::CaseSensitive);   //返回true;

(4) 比较两个字符串也是经常使用的功能,QString提供了多种比较手段:

① operator<(const QString&):比较一个字符串是否小于另一个字符串,如果是,则返回true。

② operator<=(const QString&):比较一个字符串是否小于等于另一个字符串,如果是,则返回true。

③ operator==(const QString&):比较两个字符串是否相等,如果相等,则返回true。

④ operator>=(const QString&):比较一个字符串是否大于等于另一个字符串,如果是,则返回true。

⑤ localeAwareCompare(const QString&,const QString&):静态函数,比较前后两个字符串,如果小于则返回负整数值;如果等于则返回0;如果大于则返回正整数值。该函数的比较是基于本地(locale)字符集的,而且是平台相关的。通常该函数用于向用户显示一个有序的字符串列表。

⑥ compare(const QString&,const QString&,Qt::CaseSensitivity):该函数可以指定是否进行大小写的比较,而大小写的比较是完全基于字符的Unicode编码值的,而且是非常快的,返回值类似于localeAwareCompare()函数。

3.1.3 字符串的转换

QString类提供了丰富的转换函数,可以将一个字符串转换为数值类型或者转换为其他的字符编码集。

(1) QString::toInt()函数将字符串转换为整型数值,类似的函数还有toDouble()、toFloat()、toLong()、toLongLong()等。下面举个例子说明其用法:

        QString str="125";
        bool ok;
        int hex=str.toInt(&ok,16);      //ok=true,hex=293
        int dec=str.toInt(&ok,10);      //ok=true,dec=125

其中:

● QString str="125":初始化一个"125"的字符串;

● int hex=str.toInt(&ok,16):调用QString::toInt()函数将字符串转换为整型数值。函数QString::toInt()有两个参数,第一个参数是一个bool类型的指针,用于返回转换的状态,当转换成功时设置为true,否则设置为false。第二个参数指定了转换的基数。当基数设置为0时,将会使用C语言的转换方法:如果字符串以“0x”开头,则基数为16;如果字符串以“0”开头,则基数为8;其他情况下,基数一律是10。

(2) QString提供的字符编码集的转换函数将会返回一个const char*类型版本的QByteArray,即构造函数QByteArray(const char*)构造的QByteArray对象。QByteArray类具有一个字节数组,它既可以存储原始字节(raw bytes),也可以存储传统的以“\0”结尾的8位的字符串。在Qt中,使用QByteArray比使用const char*更方便,而QByteArray也支持隐式共享。转换函数有以下几个:

toAscii():返回一个ASCII编码的8位字符串。

toLatin1():返回一个Latin-1(ISO8859-1)编码的8位字符串。

③ toUtf8():返回一个UTF-8编码的8位字符串(UTF-8是ASCII码的超级,它支持整个Unicode字符集)。

toLocal8Bit():返回一个系统本地(locale)编码的8位字符串。

下面举例说明其用法:

        QString str=" Welcome to you! ";
        QByteArray ba=str.toAscii();
        qDebug()<<ba;
        ba.append("Hello,World! ");
        qDebug()<<ba.data();

其中:

● QString str=” Welcome to you!”:初始化一个字符串对象。

● QByteArray ba=str.toAscii():通过QString::toAscii()函数,将Unicode编码的字符串转换为ASCII码的字符串,并存储在QByteArray对象ba中。

● qDebug()<<ba:使用qDebug()函数输出转换后的字符串(qDebug()支持输出Qt对象)。

● ba.append(“Hello,World!”):使用QByteArray::append()函数追加一个字符串。

● qDebug()<<ba.data():输出最后结果。

注意:NULL字符串和空(empty)字符串的区别:

一个NULL字符串就是使用QString的默认构造函数或者使用“(const char*)0”作为参数的构造函数创建的QString字符串对象;而一个空字符串是一个大小为0的字符串。一个NULL字符串一定是一个空字符串,而一个空字符串未必是一个NULL字符串。例如:

        QString().isNull();       //结果为true
        QString().isEmpty();      //结果为true
        QString(""). isNull();      //结果为false
        QString("").isEmpty();     //结果为true