收藏 分享(赏)

Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt

上传人:dcs1276 文档编号:4694203 上传时间:2019-01-07 格式:PPT 页数:65 大小:1.86MB
下载 相关 举报
Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt_第1页
第1页 / 共65页
Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt_第2页
第2页 / 共65页
Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt_第3页
第3页 / 共65页
Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt_第4页
第4页 / 共65页
Qt诺基亚官方中文教程L3_Qt的数据类型机会及文件.ppt_第5页
第5页 / 共65页
点击查看更多>>
资源描述

1、.,数据类型 集合和文 件,Qt in Education,This work is a Chinese translation of the original Qt Educational Training Materials published by Nokia: 2010 Nokia Corporation and its Subsidiary(-ies).Nokia, Qt and the Nokia and Qt logos are the registered trademarks of Nokia Corporation in Finland and other countrie

2、s worldwide.This translation was created by Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology. 2010 Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology.The enclosed Qt Educational Training M

3、aterials are provided under the Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement. The full license text is available here: http:/creativecommons.org/licenses/by-nc-sa/2.5/legalcode.,此文档内容是由诺基亚公司发布的原创Qt教育培训文档的中文翻译: 2010诺基亚公司及其附属公司。Nokia (诺基亚),Qt以及Nokia与Qt商标是Nokia公司在芬兰和全球其

4、他国家的注册商标。 该翻译版本由 华南理工大学广东省计算机网络重点实验室 创造。 2010 华南理工大学广东省计算机网络重点实验室本Qt 教育培训材料依照署名-非商业性使用-相同方式共享 2.5许可协议(Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement)发布。完整的许可证文本可以在这里找到:http:/creativecommons.org/licenses/by-nc-sa/2.5/legalcode。,管理文本,简单的C字符串是方便的,但这仅限于本地字符编码QString类试图成为现代

5、的字符串类 Unicode 和 codecs 隐式共享的性能,char *text = “Hello world!“;,QString,支持存储Unicode字符串,几乎当前在用的所有书写系统都能表示支持从不同的本地编码转换或者转成不同的本地编码提供了一个方便的字符串检查和修改的API,QString:toAscii QString:toLatin1 QString:toLocal8Bit,建立字符串,有三种建立字符串的主要方法 运算符+ 方法QStringBuilder 的方法arg 方法,QString res = QString(“Hello %1, the value is %2“).

6、arg(name).arg(42);,QString res = “Hello “ + name + “, the value is “ + QString:number(42);,QString res = “Hello “ % name % “, the value is “ % QString:number(42);,QStringBuilder,使用+运算符来连接字符串,这需要多次内存分配和字符串长度检查 一个更好的方式是包含QStringBuilder并使用操作符 该字符串生成器在连接之前一次性收集所有字符串的长度,只需执行一次内存分配,QString res = “Hello “

7、% name % “, the value is %“ % QString:number(42);,QString temp = “Hello “; temp = temp % name; temp = temp % “, the value is %“ temp = temp % QString:number(42);,QString:arg,arg方法用值来替换 %1-99 可以处理字符串,字符,整型和浮点型能在数字基数之间转换,“%1 + %2 = %3, the sum is %3“,.).arg(value, width, base, fillChar); .).arg(42, 3,

8、 16, QChar(0); / Results in 02a,.).arg(QString, . QString) .).arg(int a) .).arg(uint a) .).arg(long a) .).arg(ulong a) .).arg(qlonglong a),.).arg(qulonglong a) .).arg(short a) .).arg(ushort a) .).arg(QChar a) .).arg(char a) .).arg(double a),子串,使用left, right 和 mid访问子串如果mid不指定长度,则返回字符串的剩余部分用 replace查找

9、和替代字符串,QString s = “Hello world!“; r = s.left(5); / “Hello“ r = s.right(1); / “!“ r = s.mid(6,5); / “world“,r = s.mid(6); / “world!“,r = s.replace(“world“, “universe“); / “Hello universe!“,打印到控制台,Qt是一个主要用于可视应用的工具包,即不专注于命令行界面的 要打印, 用 qDebug 函数 它总是可用, 但是在建立发布版本时会静默 像printf 函数那样工作 (但加上 “n”) 使用qPrintabl

10、e宏很容易打印QString的文本当包含QtDebug后,能与流操作符一起使用,qDebug(“Integer value: %d“, 42); qDebug(“String value: %s“, qPrintable(myQString);,#include qDebug() “Integer value:“ 42; qDebug() “String value:“ myQString; qDebug() “Complex value:“ myQColor;,与数字间转换,把数字转换为字符串把字符串转换为数值,QString:number(int value, int base=10);

11、QString twelve = QString:number(12); / “12“ QString oneTwo = QString:number(0x12, 16); / “12“QString:number(double value, char format=g, int precision=6); QString piAuto = QString:number(M_PI); / “3.14159“ QString piScientific = QString:number(M_PI,e); / “3.141593e+00“ QString piFixedDecimal = QStri

12、ng:number(M_PI,f,2); / “3.14“,bool ok; QString i = “12“; int value = i.toInt( if(ok) / Converted ok ,bool ok; QString d = “12.36e-2“; double value = d.toDouble( if(ok) / Converted ok ,与std:(w)string一起工作,当连接第三方库和其他代码时,与标准库的字符串转换很方便 从标准库的字串转换成其他 转成标准库字符串,QString qs = “Hello world!“; std:string ss = qs

13、.toStdString(); std:wstring sws = qs.toStdWString();,std:string ss = “Hello world!“; std:wstring sws = “Hello world!“;QString qss = QString:fromStdString(ss); QString qsws = QString:fromStdWString(sws);,Empty字符串和null字符串,一个QString可以为null,即什么也没有包含它也可是empty,即包含一个空字符串,QString e = “;e.isNull(); / false e

14、.isEmpty(); / true,QString n = QString();n.isNull(); / true n.isEmpty(); / true,分割和组合,一个QString 能够被分割成子串由此产生的对象是QstringList,它可被组合成一个QString,QString whole = “Stockholm - Copenhagen - Oslo - Helsinki“; QStringList parts = whole.split(“ - “);,QString wholeAgain = parts.join(“, “);/ Results in “Stockhol

15、m, Copenhagen, Oslo, Helsinki“,QStringList,QStringList是一个专门列表类型 为存储字符串而设计提供了一个方便的作用于列表中字符串的API这个类使用隐含共享 副本修改 作为const引用传递的代价低,建立和修改字符串列表,用 操作符把字符串增加到字符串列表replaceInStrings函数能让你在QStringList的所有字符串中进行搜索和替换。,QStringList verbs;verbs = “running“ “walking“ “compiling“ “linking“;,qDebug() verbs; / (“running“,

16、 “walking“, “compiling“, “linking“) verbs.replaceInStrings(“ing“, “er“);qDebug() verbs; / (“runner“, “walker“, “compiler“, “linker“),排序与筛选,QStringList可以进行排序.筛选.及清除重复的条目,qDebug() capitals; / (“Stockholm“, “Oslo“, “Helsinki“, “Copenhagen“) capitals.sort(); qDebug() capitals; / (“Copenhagen“, “Helsinki

17、“, “Oslo“, “Stockholm“),QStringList capitalsWithO = capitals.filter(“o“); qDebug() capitalsWithO; / (“Copenhagen“, “Oslo“, “Stockholm“),capitals capitalsWithO; qDebug() capitals; / (“Copenhagen“, “Helsinki“, “Oslo“, “Stockholm“, / “Copenhagen“, “Oslo“, “Stockholm“) capitals.removeDuplicates(); qDebu

18、g() capitals; / (“Copenhagen“, “Helsinki“, “Oslo“, “Stockholm“),遍历字符串,使用操作符 和 length 函数,你可以遍历QStringList的内容另一种方法是使用at() 函数,它提供列表项的只读访问你也可以使用foreach 宏,QStringList capitals; for(int i=0; icapitals.length(); +i)qDebug() capitalsi;,QStringList capitals; foreach(const QString ,Qt的集合,QStringList接口不是唯一的字符串

19、列表。 QStringList是由QList 派生的。 QList是众多Qt容器模板类中的一个 QLinkedList - 在中间快速插入,通过迭代器 QVector - 使用连续内存,缓慢插入 QStack LIFO, 后进先出 QQueue FIFO, 先进先出 QSet 唯一值 QMap 关联数组 QHash 关联数组,比QMap快,但需要哈希 QMultiMap 通过每个键的多个值关联数组 QMultiHash 通过每个键的多个值关联数组,填充,你可以用操作符填充一个QList函数prepend, insert 和append 也可以使用,QList fibonacci; fibona

20、cci 0 1 1 2 3 5 8;,list.append(4);,QList list; list.append(2);,list.prepend(1);,list.insert(1,3);,index 0: 2,index 0: 2,index 1: 4,index 0: 1,index 1: 2,index 2: 3,index 0: 2,index 1: 3,index 2: 4,index 3: 4,删除,使用removeFirst,removeAt,removeLast从Qlist中删除列表项用takeFirst, takeAt, takeLast去得到一个列表项使用remove

21、All或removeOne删除特定值的列表项,while(list.length()list.removeFirst();,QList widgets; widgets new QWidget new QWidget; while(widgets.length()delete widgets.takeFirst();,QList list; list 1 2 3 1 2 3; list.removeAll(2); / Leaves 1, 3, 1, 3,访问,一个QList 的索引范围是0 -(length-1) 单个列表项可以用at 或者 操作符来访问。如果你能接受超出界限的情况,可以用va

22、lue。 运算符返回一个可修改的引用,for(int i=0; ilist.length(); +i)listi+;,for(int i=0; ilist.length(); +i)qDebug(“At: %d, : %d“, list.at(i), listi);for(int i=0; i100; +i)qDebug(“Value: %d”, list.value(i);,迭代 - Java风格,Qt 支持 Java 风格迭代器Java风格的迭代器指向条目之间 toFront把迭代器置于第一项前面 toBack把迭代器置于最后一项后面 用peekNext和peekPrevious 参考列表

23、项 用 next 或 previous指向列表项,item 1,item 5,item 4,item 3,item 2,i.toBack(),i.toFront(),i.peekNext() i.next(),i.peekPrevious() i.previous(),i,QListIterator iter(list);while(iter.hasNext()qDebug(“Item: %d“, iter.next();,迭代 - STL的风格,Qt 支持 STL 风格的迭代器STL的迭代器指向每个列表项,并以此作为结束标记无效项 第一项用begin来返回 结束标志用end返回 * 操作符关

24、联项的值 当你向后遍历访问之前,必须移动操作符,item 1,item 5,item 4,item 3,item 2,begin(),i,end(),end(),*i,for(QList:ConstIterator iter=list.begin(); iter!=list.end(); +iter)qDebug(“Item: %d“, *iter);,懒惰式的迭代,遍历整个集合,使用foreach警告!当按值返回时要确保复制列表,QStringList texts; foreach(QString text, texts)doSomething(text);,QStringList text

25、s; foreach(const QString ,const QList sizes = splitter-sizes(); QList:const_iterator i; for(i=sizes.begin(); i!=sizes.end(); +i)processSize(*i);,与STL的交互,QList 能与相应的std:list相互转换与STL的相互转换意味着对列表内容进行深度复制 不存在隐含共享,QList list; list stlList = list.toStdList();QList otherList = QList:fromStdList(stlList);,其他

26、集合,谁能代替QList,它们跟QList有何区别?QLinkedList 用索引访问缓慢 使用迭代器很快 快速(恒定时间)在列表的中间插入QVector 使用连续的内存空间 插入和置首缓慢,其他集合,注意,摊销行为(amortized behavior)是指在实时环境中不可预知的次数 其他集合是以Qlist为基础的 QStringList QStack QQueue QSet,特殊情况 - QStack,堆,一个后进先出(LIFO)的容器后进先出列表项压入堆 列表项弹出堆 用top()取出顶项,s.push(),s.pop(),QStack stack; stack.push(1); sta

27、ck.push(2); stack.push(3); qDebug(“Top: %d“, stack.top(); / 3 qDebug(“Pop: %d“, stack.pop(); / 3 qDebug(“Pop: %d“, stack.pop(); / 2 qDebug(“Pop: %d“, stack.pop(); / 1 qDebug(“isEmpty? %s“, stack.isEmpty()?“yes“:“no“);,特殊情况- QQueue,队列,一个先进先出( FIFO)的 容器 先进先出项排队进入队列 项从队列中出列 取第一项可以用head(),s.enqueue(),s.

28、dequeue(),QQueue queue; queue.enqueue(1); queue.enqueue(2); queue.enqueue(3); qDebug(“Head: %d“, queue.head(); / 1 qDebug(“Pop: %d“, queue.dequeue(); / 1 qDebug(“Pop: %d“, queue.dequeue(); / 2 qDebug(“Pop: %d“, queue.dequeue(); / 3 qDebug(“isEmpty? %s“, queue.isEmpty()?“yes“:“no“);,特殊情况- QSet,一个集合包含

29、值,但对每个值只有一个实例。 可以判断一个值是否是集合的一部分也可以遍历一个集合,看到所有的值可以转换一个QList 到一个QSet,QSet primes; primes 2 3 5 7 11 13; for(int i=1; i=10; +i)qDebug(“%d is %sprime“, i, primes.contains(i)?“:“not “);,foreach(int prime, primes)qDebug(“Prime: %d“, prime);,QList list; list set = list.toSet(); qDebug() list; / (1, 1, 2, 2

30、, 2, 3, 3, 5) qDebug() set; / (1, 2, 3, 5),键 - 值集合,QMap和QHash类让你创建关联数组,QHash hash;hash“Helsinki“ = 1310755; hash“Oslo“ = 1403268; hash“Copenhagen“ = 1892233; hash“Stockholm“ = 2011047;foreach(const QString ,QMap map;map“Helsinki“ = 1310755; map“Oslo“ = 1403268; map“Copenhagen“ = 1892233; map“Stockho

31、lm“ = 2011047;foreach(const QString ,使用QMap,QMap 类需要操作符 来定义关键类型此操作符用来保持键的顺序 填充使用运算符或 insert来完成对于读取,用value 结合contains,if(map.contains(“Oslo“)qDebug(“Oslo: %d“, map.value(“Oslo“);qDebug(“Berlin: %d“, map.value(“Berlin“,42);,map“Stockholm“ = 2011047;map.insert(“London“, 13945000);,哈希,QMap使用了给定的模板中的类型的键

32、 QHash 使用 uint 值 key类型散列到一个uint值运用uint 值可能提高性能 哈希值表示键没有排序 哈希函数必须设法避免碰撞,以达到良好的性能,使用 QHash,键类型必须提供一个qHash 函数和操作符= 到QHash相对Qmap,填充和读取相同,uint qHash(const Person ,一键多值,QMultiMap和QMultiHash提供支持一键多值的关联数组,QMultiMap multiMap;multiMap.insert(“primes“, 2); multiMap.insert(“primes“, 3); multiMap.insert(“primes“

33、, 5);. multiMap.insert(“fibonacci“, 8); multiMap.insert(“fibonacci“, 13);foreach(const QString ,休息,Qt的类型定义,C + +中没有定义严格跨平台类型的大小sizeof(int) = ?对于跨平台的代码,以严格的方式定义的所有类型是很重要的,ARM = 4 bytes x86 = 4 bytes IA64 = 8 bytes .,跨平台类型,所有类型都定义在头中,Qt的复杂类型,Qt提供了多个复杂的类和类型,QColor,QBrush,QRect,QPoint,QString,QSize,QLis

34、t,QImage,QByteArray,QPixmap,QPen,QFont,QVariant,有时候,希望能够通过一个普通的接口返回任何类型QVariant类可以被视为一个联合 创造一个Qt的类型联合是不可能,因为联合需要默认的构造函数 变异类可以包含自定义的复杂类型,例如QColor属于QtGui,QVariant属于QtCore 一旦它们被声明,联合就不能扩展到更多类型,const QVariant ,使用QVariant,基本类型用构造函数和 toType 函数处理非QtCore类型,如自定义类型,使用setValue 函数和模板 value 函数来处理,QVariant v; QCo

35、lor c(Qt:red); qDebug() (); / After: QColor(ARGB 1, 1, 0, 0) qDebug() “After:“ c;,QVariant v; int i = 42; qDebug() “Before:“ i; / Before: 42 v = i; i = v.toInt(); qDebug() “After:“ i; / After: 42,自定义的复杂类型,我们实现一个小类,包含一个人的名字和年龄,class Person public:Person();Person(const Person ,Person:Person() : m_age(

36、-1) .void Person:setAge(int a) m_age = a; bool Person:isValid() const return (m_age = 0); ,QVariant与Person对象,试图通过一个QVariant对象传递一个Person对象失败在元类型系统中声明这一类型解决了问题,class Person . ;Q_DECLARE_METATYPE(Person)#endif / PERSON_H,qmetatype.h:200: error: qt_metatype_id is not a member of QMetaTypeId,QVariant与Per

37、son对象,当类型注册成为一个元类型, Qt能把它存储在一个Qvariant中要求声明类型 Public default constructor Public copy constructor Public destructor,QVariant var; var.setValue(Person(“Ole“, 42); Person p = var.value(); qDebug(“%s, %d“, qPrintable(p.name(), p.age();,然后,它中断了.,当与信号和槽工作,大部分连接是直接的 直接连接时,类型可工作 排队的连接,即非阻塞,异步的时候,这些类型不能工作(比如

38、跨越线程边界),connect(src, SIGNAL(), dest, SLOT(), Qt:QueuedConnection);.QObject:connect: Cannot queue arguments of type Person (Make sure Person is registered using qRegisterMetaType().),注册类型,错误信息告诉我们如何解决问题 qRegisterMetaType函数必须在连接建立之前被调用 (通常从main开始),int main(int argc, char *argv) qRegisterMetaType();.,文

39、件和文件系统,在跨平台中的文件和目录带来许多问题 系统是否有驱动器,或只是一个根? 路径是否被“/” 或 “”隔开? 系统在哪里存储临时文件? 用户在哪里存储文档? 应用程序在哪里存储?,路径,用QDir 类去处理路径学会用静态函数去初始化,QDir d = QDir:root(); / C:/ on windowsQDir:current() / Current directory QDir:home() / Home directory QDir:temp() / Temporary directory/ Executable directory path QDir(QApplicatio

40、n:applicationDirPath(),QDir d = QDir(“C:“);,找目录内容,entryInfoList返回该目录内容的信息列表你可以添加过滤器以跳过文件或目录,QFientryInfoListleInfoList infos = QDir:root().entryInfoList(); foreach(const QFileInfo ,QDir:Dirs QDir:Files QDir:NoSymLinksQDir:Readable QDir:Writable QDir:ExecutableQDir:Hidden QDir:System,找目录内容,QDir:Name

41、QDir:Time QDir:Size QDir:TypeQDir:DirsFirst QDir:DirsLastQDir:Reversed,QFileInfoList infos = QDir:root().entryInfoList(QDir:Dirs, QDir:Name); foreach(const QFileInfo ,你也可以指定排序顺序从主目录根据名字排列所有目录,找目录内容,最后,可以添加名字过滤器,QFileInfoList infos =dir.entryInfoList(QStringList() “*.cpp“ “*.h“, QDir:Files, QDir:Name

42、); foreach(const QFileInfo ,QFileInfo,每个 QFileInfo 对象都有许多函数 absoluteFilePath 某项的完整路径isDir / isFile / isRoot 项的类型isWriteable / isReadable / isExecutable 文件的权限,/home/john/the-archive.tar.gz,fileName,absolutePath path,baseName,completeSuffix,suffix,打开和读取文件,QFile 用来访问文件,QFile f(“/home/john/input.txt“);i

43、f (!f.open(QIODevice:ReadOnly)qFatal(“Could not open file“);,while(!f.atEnd() QByteArray data = f.read(160);processData(data); ,QByteArray data = f.readAll(); processData(data);,f.close();,写文件,QFile f(“/home/john/input.txt“);if (!f.open(QIODevice:WriteOnly)qFatal(“Could not open file“);QByteArray da

44、ta = createData(); f.write(data);f.close();,写入文件时,用WriteOnly 模式打开文件,用写函数向文件添加数据文件也可用ReadWrite 模式打开 Append或Truncate标志可以与写入模式相结合以追加数据到文件或截断它(即清除文件以前的内容),if (!f.open(QIODevice:WriteOnly|QIODevice:Append),QIODevice,QFile由QIODevice派生 构造函数QTextStream和QDataStream以QIODevice指针为参数,而不是QFile指针 QIODevice的实现 QBuf

45、fer 读写到内存缓冲 区 QextSerialPort 串行(RS232) 通讯 (第三方) QAbstractSocket - TCP,SSL和UDP套接字类的基 QProcess 读写进程的标准输入和输出,流操作与文件,读取和写入函数在许多情况下显得尴尬 如处理复杂类型等一个现代的方案是使用流操作Qt的提供两种流操作 用于处理文本文件 用于处理二进制文件格式,QTextStream,QTextStream 类处理基于文本的文件读写 这个类能 感知编解码(默认是使用区域设置,但也可以显式设置) 感知行和字 感知数字,写入文本流,使用操作符 和修饰符, 跟使用 STL 的流类似,QFile

46、f(.); if(!f.open(QIODevice:WriteOnly)qFatal(“Could not open file“);QTextStream out(,Primes: 2 3 5 7,使用文本流读取,可以逐行读文件可以提取单词和数字用 atEnd 去判断是否到达文件末尾,QTextStream in(,QTextStream in(,处理二进制文件,QDataStream类用于字节流 保证字节顺序(默认大端) 支持基本类型 支持Qt的复杂类型 支持添加自定义的复杂类型,if (!f.open(QIODevice:WriteOnly)qFatal(“Could not open

47、file“);QDataStream ds(,数据流作为一种文件格式,当基于QDataStream的文件格式时有一些细节需要注意 版本控制 随着Qt的结构演变,它们的二进制序列化格式也随之改变。使用QDataStream:setVersion,可以显式强制使用特定的序列化格式。 类型信息 - Qt不添加类型信息,所以需要记录下你所存储的类型是以什么样的顺序存储。 字节序 - Qt的数据流是默认大端,但在使用类以处理旧系统文件格式的时候,可以使用QDataStream:setByteOrder来设置字节顺序。,数据流作为一种文件格式,QFile f(“file.fmt“); if (!f.ope

48、n(QIODevice:WriteOnly)qFatal(“Could not open file“);QDataStream out(,QFile f(“file.fmt“); if (!f.open(QIODevice:ReadOnly)qFatal(“Could not open file“);QDataStream in(,流化自定义类型,通过实现流操作符,自定义类型可以跟数据流互相转换,QDataStream ,流化自定义类型,为了流化包含在QVariant对象中的自定义类型,流操作符必须注册当变量被流化后,它增加了数据类型的名称,以确保它之后可以从流中恢复,qRegisterMetaTypeStreamOperators(“Person“);,00: 0x00 0x00 0x00 0x7f 0x00 0x00 0x00 0x00 _ 08: 0x07 0x50 0x65 0x72 0x73 0x6f 0x6e 0x00 _Person_ 16: 0x00 0x00 0x00 0x06 0x00 0x4f 0x00 0x6c _O_l 24: 0x00 0x65 0x00 0x00 0x00 0x2a e_*,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 实用文档 > 简明教程

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报