首页 > 其他 > 详细

Qt学习(13)

时间:2015-12-28 14:07:36      阅读:568      评论:0      收藏:0      [点我收藏+]

Qt学习(13)——使用 QString

        本节介绍 QString 的常见使用,包含 C++ 基本类型和 QString 的互相转换、QString 涉及的运算符、QString 子串查询和操作、利用 QTextStream 对 QString 做输入输出操作等,最后通过一个示例集成测试函数,展示 QString 用法。本节内容较多,可分几次尝试代码,凡是原理性质的内容需要理解,而罗列性质的内容不用死记的,可以到用的时候查看文档。

1、QString和QChar简介

      QString是由一系列16bit字符QChar组成的字符串,以NULL字符结尾(末尾的NULL不计入字符串长度)。QChar是一个Unicode 4.0标准的字符,对于超过16bit范围的国际码字符,QString里采用相邻的一对QChar来表示。QString使用的其实是UTF-16的双字节编码,tr函数就是将UTF-8变长编码的字符串转成QString运行时的内码。UTF-8编码是属于通用的存储交换格式,但这种编码的缺点就是一个字符的长度不固定,这对字符串操作效率是有影响的,因为要先确定每个字符的长度。因此QString采用固定长度字符单元的UTF-16编码,这对程序运行时字符串比较、查询操作效率更高。上一节 中“运行时QString与多种编码格式转换” 表格中 utf16() 和 unicode() 函数都没有用 to 前缀,因为这两个函数没有做转换,它们返回的就是 QString  运行时的内码,同 data() 函数。tr 函数不仅可以用于支持国际化翻译,并且能自动将字符串的存储交换格式 UTF-8 转换成运行时的 UTF-16 内码,返回转换过后得到的QString 对象。

        字符串之间经常有手动复制或者通过函数参数、函数返回值等复制操作,QString为了优化内存使用效率,避免出现大量相同内容的字符串副本,QString对复制过程采用隐式共享机制(implicit sharing),比如执行字符串对象str1 = str2时,如果这两个对象字符串内容都没有后续的改变,那么它们会指向同一块字符串数据,而如果其中之一发生改变,字符串数据块的复制过程才会发生,这样能最大程度地节省内存,而且在传QString类型参数或返回值时,避免了大量数据块的复制过程,优化了程序运行效率。

       QString内码是UTF-16,而标准C++的字符串是UTF-8编码的,Qt针对标准C++字符串也提供了QByteArray类,用于操作UTF-8编码以及其他本地化字符串(如GBK、Big5)、字节数组(不以NULL结尾的纯数据)等,QByteArray类下一节会介绍。

2、基本类型与字符串互相转换

        在编程时经常会出现把数值如 800 转成字符串 "800",或者反过来把字符串转成数值等情况,本小节罗列 C++ 基本的数值类型和 Qt 对这些类型的别称,然后展示这些基本类型和 QString 对象的互相转换,并编写一些测试函数来示范效果。

基本类型 Qt别称 转入函数 转出函数 描述
short qint16 arg或setNum toShort 2 字节长度,有符号短整型。
unsigned short ushort、quint16 arg或setNum toUShort 2 字节长度,无符号短整型。
int qint32 arg或setNum toInt 4 字节长度,有符号整型。
unsigned int uint、quint32 arg或setNum toUInt 4 字节长度,无符号整型。
long arg或setNum toLong 有符号长整型,对于 32 位编程 long 是 4 字节长度,对于 64 位编程是 8 字节长度。
unsigned long ulong arg或setNum toULong 无符号长整型,对于 32 位编程 unsigned long 是 4 字节长度,对于 64 位编程是 8 字节长度。
long long qlonglong、qint64 arg或setNum toLongLong 8 字节长度,有符号长长整型。
unsigned long long qulonglong、quint64 arg或setNum toULongLong 8 字节长度,无符号长长整型。
float 默认情况下无 arg或setNum toFloat 4 字节长度,单精度浮点数。
double 默认情况对应 qreal arg或setNum toDouble 8 字节长度,双精度浮点数。

 这些基本的数值类型转为 QString 对象都是使用重载的 arg 或 setNum 函数,而 QString  对象转出为其他类型使用单独命名的函数。Qt 对这些类型的别称都定义在头文件 <QtGlobal> 里面,由于其他绝大多数 Qt 头文件都包含了该全局头文件,所以通常不需要自己手动去包含它的。对于上表需要说明的两点:一是 long 和 ulong 长度是根据操作系统和编译器确定的,32 位编程就是 32 位,64 位编程就是 64 位;二是实数 qreal 默认情况下都是对应 double ,例外情况是在编译 Qt 类库本身时配置了 -qreal float 选项参数,这种例外情况极少,通常都不用管的
        首先来介绍一下转入函数,对于整数类型,setNum 函数声明是完全类似的,以 int 为例:

QString & setNum(int n, int base = 10)

第一个参数就是需要转换的整数,第二个参数是转换之后的目标字符串进制基数,比如转成十六进制字符串、八进制字符串等,默认是转成十进制的字符串。setNum 函数设置好字符串内容后返回 QString 对象自身的引用。

对于浮点数类型,setNum 函数声明有些区别,以 double 为例:

QString & QString::?setNum(double n, char format = g, int precision = 6)

第一个参数是需要转换的浮点数,第二个是转换之后的目标字符串格式(‘e‘, ‘E‘, ‘f‘, ‘g‘ ,  ‘G‘),第三个是目标字符串显示的浮点数精度,默认是 6 。浮点数的格式是与 C 语言类似的,如下所述:

  • ‘e‘:科学计数法,小写 e,如 [-]9.9e[±]999。
  • ‘E‘:科学计数法,大写 E,如 [-]9.9E[±]999。
  • ‘f‘:定点数显示,[-]9.9。
  • ‘g‘: 自动选择用科学计数法或定点数显示,哪种方式最简洁就用哪个,科学计数法的 e 小写。
  • ‘G‘:自动选择用科学计数法或定点数显示,哪种方式最简洁就用哪个,科学计数法的 E 大写。

setNum 函数示范代码:

void Test_setNum() {
    QString strTest;
    //to Hex string
    short numHex = 127;
    strTest.setNum(numHex, 16);
    qDebug()<<"Hex: "<<strTest;

    //to Oct string
    int numOct = 63;
    strTest.setNum(numOct, 8);
    qDebug()<<"Oct: "<<strTest;

    //to normal Dec string
    long numDec = 800;
    strTest.setNum(numDec);
    qDebug()<<"Normal: "<<strTest;

    //to float string
    float numFixed = 123.78999;
    strTest.setNum(numFixed, f, 3);
    qDebug()<<"Fixed: "<<strTest;

    //to scientific double string
    double numScientific = 456.78999;
    strTest.setNum(numScientific, e, 6);
    qDebug()<<"Scientific: "<<strTest;
}

这个测试函数运行结果就不贴出来了,读者自己手动去试试看。

        接下来重点介绍 arg 函数,这是最常用也是最具特色的。arg 函数无所不包,它的参数可以是数值类型、字符串类型,并且可以串联,格式化参数里还可以指定顺序、重复使用参数等等。对于数值类型,它的声明与 setNum 比较类似,以 int 和 double 为例:

QString arg(int a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char(   )) const 

 

QString arg(double a, int fieldWidth = 0, char format = g, int precision = -1, QChar fillChar = QLatin1Char(   )) const

        注意 arg 函数声明末尾的 const,这个函数不会改变字符串对象本身的内容,而是会返回一个全新的 QString对象,所以使用这个函数时,必须用它的返回值。
        对于整数类型,它的声明多出来两个:fieldWidth 是指生成的目标字符串宽度,0 表示自动设置长度,最后的 fillChar 是填充字符,如果设置的域宽比较大,多余的空位就会使用这个填充字符填满。
        对于浮点数类型,多出来的 fieldWidth 也是生成的目标字符串宽度,fillChar 也是填充字符。默认的填充字符是空格,QLatin1Char 代表一个字节长度的拉丁字符,与 ASCII 码字符差不多。QLatin1Char 有对应的类 QLatin1String,因为仅支持单字节拉丁字符,不支持国际化,它应用的比较少。 
        arg 函数比 setNum 函数功能更强大,可以设置目标字符串宽度和填充字符。arg 函数还可以用字符串作为参数,可以将一个字符串填充到另一个里面,比如下面这个函数声明:

QString arg(const QString & a, int fieldWidth = 0, QChar fillChar = QLatin1Char(   )) const

这个声明和数值类型声明差不多,也可以设置目标字符串宽度和填充字符。

函数声明介绍到这,下面看看这个函数该怎么用。arg 函数的使用方式很特别,它的串联方式也很灵活,来看看示例代码:

 

void Test_arg() {
    //使用 strResult 存储 arg 返回的新对象
    QString strResult;

    //Dec
    long numDec = 800;
    QString strMod = QObject::tr("Normal: %1");
    strResult = strMod.arg(numDec);  //%1是占位符,第一个arg函数参数变量转后的字符串填充到 %1 位置
    qDebug()<<"Mod: "<<strMod<<" \t Result: "<<strResult;

    //Oct
    int numOct = 63;
    strResult = QObject::tr("Oct: %1").arg(numOct, 4, 8, QChar(0));  //numOct转换后为4字符域宽,8进制,填充0
    qDebug()<<strResult;

    //Hex
    short numHex = 127;
    QString strPrefix = QObject::tr("0x");
    //占位符里可填充数值转的字符串,也可以直接填充原有的字符串
    strResult = QObject::tr("Hex: %1%2").arg(strPrefix).arg(numHex, 0, 16);  //串联:第一个arg函数参数填充到%1,第二个arg填充到%2
    qDebug()<<strResult;

    //double
    double numReal = 123.78999;
    strResult = QObject::tr("Fixed: %1 \t Scientific: %2").arg(numReal, 0, f).arg(numReal, 0, e, 3);
    qDebug()<<strResult;

    //占位符可重复,也可乱序
    int one = 1;
    int two = 2;
    int three = 3;
    strResult = QObject::tr("%1 小于 %2,%1 小于 %3,%3 大于 %2 。").arg(one).arg(two).arg(three);
    qDebug()<<strResult;
}

 上面都是通过 tr 函数封装了一个临时的 QString 对象,然后调用该临时对象的 arg 函数实现数值类型转成格式化字符串,填充到占位符里面。这个工作原理与 sprintf 等 C 语言函数类似,sprintf 函数使用 %n 、%s  之类的格式占位符,QString 的实现方式不一样,它使用 % 加数字的占位方式,%1 对应后面串联的第一个 arg 函数,%2 对应后面串联的第二个 arg 函数,以此类推。具体的 %1 或 %2 等替换后的格式,由对应的 arg 函数来决定,QString 里有非常多的重载 arg 函数,每个 arg 函数对应一个类型,因此 %1 既可以填充数值类型转化后的格式化字符串,也可以填充其他原有的字符串。下面逐个解释一下各个 arg 函数意义:

long numDec = 800;     
QString strMod = QObject::tr("Normal: %1"); strResult = strMod.arg(numDec); //%1是占位符,第一个arg函数参数变量转后的字符串填充到 %1 位置 qDebug()<<"Mod: "<<strMod<<" \t Result: "<<strResult;

 

Qt学习(13)

原文:http://www.cnblogs.com/wyxsq/p/5082206.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!