




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、.数据类型集合和文件Qt in EducationThis work is a Chinese translation of the original Qt Educational Training Materials published by Nokia: 2021 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 countries wor
2、ldwide.This translation was created by Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology. 2021 Communication and Computer Network Laboratory of Guangdong Province, South China University of Technology.The enclosed Qt Educational Training Materi
3、als are provided under the Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement. The full license text is available here: ://licenses/by-nc-sa/2.5/legalcode. 此文档内容是由诺基亚公司发布的原创Qt教育培训文档的中文翻译: 2021诺基亚公司及其附属公司。Nokia (诺基亚),Qt以及Nokia与Qt商标是Nokia公司在芬兰和全球其他国家的注册商标。
4、 该翻译版本由 华南理工大学广东省计算机网络重点实验室 创造。 2021 华南理工大学广东省计算机网络重点实验室本Qt 教育培训材料依照署名-非商业性使用-相同方式共享 2.5许可协议Creative Commons Attribution-Non-Commercial-Share Alike 2.5 License Agreement发布。完整的许可证文本可以在这里找到: ://licenses/by-nc-sa/2.5/legalcode。 管理文本简单的C字符串是方便的,但这仅限于本地字符编码QString类试图成为现代的字符串类Unicode 和
5、codecs隐式共享的性能char *text = Hello world!;QString支持存储Unicode字符串,几乎当前在用的所有书写系统都能表示支持从不同的本地编码转换或者转成不同的本地编码提供了一个方便的字符串检查和修改的APIQString:toAscii QString:toLatin1 QString:toLocal8Bit建立字符串有三种建立字符串的主要方法运算符+ 方法QStringBuilder 的方法arg 方法QString res = QString(Hello %1, the value is %2) .arg(name) .arg(42);QString r
6、es = Hello “ + name + “, the value is + QString:number(42);QString res = Hello “ % name % “, the value is % QString:number(42);QStringBuilder使用+运算符来连接字符串,这需要屡次内存分配和字符串长度检查一个更好的方式是包含QStringBuilder并使用操作符该字符串生成器在连接之前一次性收集所有字符串的长度,只需执行一次内存分配QString res = Hello “ % name % “, the value is % % QString:numb
7、er(42);QString temp = Hello “;temp = temp % name;temp = temp % “, the value is % temp = temp % QString:number(42);分成多个小步骤连接字符串会降低性能QString:argarg方法用值来替换 %1-99 可以处理字符串,字符,整型和浮点型能在数字基数之间转换%1 + %2 = %3, the sum is %3.).arg(value, width, base, fillChar);.).arg(42, 3, 16, QChar(0); / Results in 02a.).arg
8、(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)n的所有实例都被替换每次上限为9个参数 子串使用left, right 和 mid访问子串如果mid不指定长度,那么返回字符串的剩余局部用 replace查找和替代字符串QString s = Hello world!
9、;r = s.left(5); / Hellor = s.right(1); / !r = s.mid(6,5); / worldr = s.mid(6); / world!r = s.replace(world, universe); / Hello universe!打印到控制台Qt是一个主要用于可视应用的工具包,即不专注于命令行界面的要打印, 用 qDebug 函数它总是可用, 但是在建立发布版本时会静默像printf 函数那样工作 (但加上 “n)使用qPrintable宏很容易打印QString的文本当包含QtDebug后,能与流操作符一起使用qDebug(Integer value
10、: %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);QString twelve = QString:number(12); / 12QString oneTwo = QString:number(0 x1
11、2, 16); / 12QString:number(double value, char format=g, int precision=6);QString piAuto = QString:number(M_PI); / 3.14159QString piScientific = QString:number(M_PI,e); / 3.141593e+00QString piFixedDecimal = QString:number(M_PI,f,2); / 3.14bool ok;QString i = 12;int value = i.toInt(&ok);if(ok) / Conv
12、erted okbool ok;QString d = 12.36e-2;double value = d.toDouble(&ok);if(ok) / Converted ok不能处理千分位与std:(w)string一起工作当连接第三方库和其他代码时,与标准库的字符串转换很方便从标准库的字串转换成其他 转成标准库字符串QString qs = Hello world!;std:string ss = qs.toStdString();std:wstring sws = qs.toStdWString();std:string ss = Hello world!;std:wstring sw
13、s = Hello world!;QString qss = QString:fromStdString(ss);QString qsws = QString:fromStdWString(sws);假定为ASCIIEmpty字符串和null字符串一个QString可以为null, 即什么也没有包含它也可是empty,即包含 一个空字符串QString e = ;e.isNull(); / falsee.isEmpty(); / trueQString n = QString();n.isNull(); / truen.isEmpty(); / true相对于一个empty字符串来说,传递没有
14、字符的串是非常有用的,见QInputDialog:gettext 当取消时返回一个null字符串分割和组合一个QString 能够被分割成子串由此产生的对象是QstringList,它可被组合成一个QStringQString whole = Stockholm - Copenhagen - Oslo - Helsinki;QStringList parts = whole.split( - );QString wholeAgain = parts.join(, ); / Results in Stockholm, Copenhagen, Oslo, HelsinkiQStringListQS
15、tringList是一个专门列表类型为存储字符串而设计 提供了一个方便的作用于列表中字符串的API这个类使用隐含共享副本修改作为const引用传递的代价低建立和修改字符串列表用 操作符把字符串增加到字符串列表replaceInStrings函数能让你在QStringList的所有字符串中进行搜索和替换。 QStringList verbs; verbs = running walking compiling linking; qDebug() verbs; / (running, walking, compiling, linking) verbs.replaceInStrings(ing,
16、er); qDebug() verbs; / (runner, walker, compiler, linker) 排序与筛选QStringList可以进行排序.筛选.及去除重复的条目qDebug() capitals; / (Stockholm, Oslo, Helsinki, Copenhagen) capitals.sort();qDebug() capitals; / (Copenhagen, Helsinki, Oslo, Stockholm) QStringList capitalsWithO = capitals.filter(o);qDebug() capitalsWithO;
17、 / (Copenhagen, Oslo, Stockholm) capitals capitalsWithO;qDebug() capitals; / (Copenhagen, Helsinki, Oslo, Stockholm, / Copenhagen, Oslo, Stockholm) capitals.removeDuplicates();qDebug() capitals; / (Copenhagen, Helsinki, Oslo, Stockholm) 默认区分大小 写遍历字符串使用操作符 和 length 函数,你可以遍历QStringList的内容另一种方法是使用at()
18、函数,它提供列表项的只读访问你也可以使用foreach 宏QStringList capitals;for(int i=0; icapitals.length(); +i) qDebug() capitalsi;QStringList capitals;foreach(const QString &city, capitals) qDebug() city;Qt的集合QStringList接口不是唯一的字符串列表。 QStringList是由QList 派生的。QList是众多Qt容器模板类中的一个QLinkedList - 在中间快速插入,通过迭代器QVector - 使用连续内存,缓慢插入
19、QStack LIFO, 后进先出QQueue FIFO, 先进先出QSet 唯一值QMap 关联数组QHash 关联数组,比QMap快,但需要哈希QMultiMap 通过每个键的多个值关联数组QMultiHash 通过每个键的多个值关联数组关联到Qlist的快慢将是我们的参考和标准填充你可以用操作符填充一个QList函数prepend, insert 和append 也可以使用QList fibonacci;fibonacci 0 1 1 2 3 5 8;list.append(4);QList list;list.append(2);list.prepend(1);list.insert(
20、1,3);index 0: 2index 0: 2index 1: 4index 0: 1index 1: 2index 2: 3index 0: 2index 1: 3index 2: 4index 3: 4删除使用removeFirst,removeAt,removeLast从Qlist中删除列表项用takeFirst, takeAt, takeLast去得到一个列表项使用removeAll或removeOne删除特定值的列表项while(list.length() list.removeFirst();QList widgets;widgets new QWidget new QWidg
21、et;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 或者 操作符来访问。如果你能接受超出界限的情况,可以用value。 运算符返回一个可修改的引用for(int i=0; ilist.length(); +i) listi+;for(int i=0; ilist.length(); +i) qDebug(At: %d, : %d, li
22、st.at(i), listi);for(int i=0; i100; +i) qDebug(“Value: %d, list.value(i);当索引超出范围时返回默认构造值迭代 - Java风格Qt 支持 Java 风格迭代器Java风格的迭代器指向条目之间toFront把迭代器置于第一项 前面toBack把迭代器置于最后一 项后面用peekNext和peekPrevious参考列表项用 next 或 previous指向列表项item 1item 5item 4item 3item 2i.toBack()i.toFront()i.peekNext()i.next()i.peekPrevi
23、ous()i.previous()iQListIterator iter(list); while(iter.hasNext() qDebug(Item: %d, iter.next();如果需要修改列表项,使用QMutableListIterator均返回一个值并迈向列表的下一个位置迭代 - STL的风格Qt 支持 STL 风格的迭代器STL的迭代器指向每个列表项,并以此作为结束标记无效项第一项用begin来返回结束标志用end返回* 操作符关联项的值 当你向后遍历访问之前, 必须移动操作符item 1item 5item 4item 3item 2begin()iend()end()*if
24、or(QList:ConstIterator iter=list.begin(); iter!=list.end(); +iter) qDebug(Item: %d, *iter);如果你需要修改列表项,使用迭代器STL和Qt两者的命名可以使用。Iterator|iterator和ConstIterator | const_iterator懒惰式的迭代遍历整个集合,使用foreach警告!当按值返回时要确保复制列表QStringList texts;foreach(QString text, texts) doSomething(text);QStringList texts;foreach(
25、const QString &text, texts) doSomething(text);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 0 1 1 2 3 5 8
26、13;std:list stlList = list.toStdList();QList otherList = QList:fromStdList(stlList);从Qt 列表到STL列表从STL列表到 Qt 列表其他集合谁能代替QList,它们跟QList有何区别?QLinkedList用索引访问缓慢使用迭代器很快快速恒定时间在列表的中间插入QVector使用连续的内存空间插入和置首缓慢其他集合注意,摊销行为amortized behavior是指在实时环境中不可预知的次数其他集合是以Qlist为根底的QStringListQStackQQueueQSetCollectionIndex
27、accessInsertPrependAppendQListO(1)O(n)Amort. O(1)Amort. O(1)QLinkedListO(n)O(1)O(1)O(1)QVectorO(1)O(n)O(n)Amort. O(1)特殊情况 - QStack堆,一个后进先出LIFO的容器 后进先出列表项压入堆列表项弹出堆用top()取出顶项s.push()s.pop()QStack stack;stack.push(1);stack.push(2);stack.push(3);qDebug(Top: %d, stack.top(); / 3qDebug(Pop: %d, stack.pop(
28、); / 3qDebug(Pop: %d, stack.pop(); / 2qDebug(Pop: %d, stack.pop(); / 1qDebug(isEmpty? %s, stack.isEmpty()?yes:no);特殊情况- QQueue队列,一个先进先出 FIFO的 容器先进先出项排队进入队列项从队列中出列取第一项可以用head()s.enqueue()s.dequeue()QQueue queue;queue.enqueue(1);queue.enqueue(2);queue.enqueue(3);qDebug(Head: %d, queue.head(); / 1qDebu
29、g(Pop: %d, queue.dequeue(); / 1qDebug(Pop: %d, queue.dequeue(); / 2qDebug(Pop: %d, queue.dequeue(); / 3qDebug(isEmpty? %s, queue.isEmpty()?yes:no);特殊情况- QSet一个集合包含值,但对每个值只有一个实例。可以判断一个值是否是集合的一局部也可以遍历一个集合,看到所有的值可以转换一个QList 到一个QSetQSet primes;primes 2 3 5 7 11 13;for(int i=1; i=10; +i) qDebug(%d is %sp
30、rime, i, primes.contains(i)?:not );foreach(int prime, primes) qDebug(Prime: %d, prime);QList list;list 1 1 2 2 2 3 3 5;QSet set = list.toSet();qDebug() list; / (1, 1, 2, 2, 2, 3, 3, 5)qDebug() set; / (1, 2, 3, 5)键 - 值集合QMap和QHash类让你创立关联数组QHash hash;hashHelsinki = 1310755;hashOslo = 1403268;hashCopen
31、hagen = 1892233;hashStockholm = 2021047;foreach(const QString &key, hash.keys() qDebug(%s, qPrintable(key);QMap map;mapHelsinki = 1310755;mapOslo = 1403268;mapCopenhagen = 1892233;mapStockholm = 2021047;foreach(const QString &key, map.keys() qDebug(%s, qPrintable(key);if(map.contains(Oslo) qDebug(Os
32、lo: %d, map.value(Oslo);使用QMap QMap 类需要操作符 来定义关键类型 此操作符用来保持键的顺序填充使用运算符或 insert来完成对于读取,用value 结合containsif(map.contains(Oslo) qDebug(Oslo: %d, map.value(Oslo);qDebug(Berlin: %d, map.value(Berlin,42);mapStockholm = 2021047;map.insert(London, 13945000);可选默认值。如果没有指定一个默认值将返回构造值用 value 而不是 以避免误增加项哈希QMap使用
33、了给定的模板中的类型的键QHash 使用 uint 值key类型散列到一个uint值运用uint 值可能提高性能哈希值表示键没有排序哈希函数必须设法防止碰撞,以到达良好的性能使用 QHash键类型必须提供一个qHash 函数和操作符= 到QHash相对Qmap,填充和读取相同uint qHash(const Person &p) return p.age() + qHash(();bool operator=(const Person &first, const Person &second) return (() = () & (firs
34、t.age() = second.age();哈希函数应该根据已知的启发式优化一键多值QMultiMap和QMultiHash提供支持一键多值的关联数组QMultiMap multiMap;multiMap.insert(primes, 2);multiMap.insert(primes, 3);multiMap.insert(primes, 5); .multiMap.insert(fibonacci, 8);multiMap.insert(fibonacci, 13);foreach(const QString &key, multiMap.uniqueKeys() QList value
35、s = multiMap.values(key); QStringList temp; foreach(int value, values) temp QString:number(value); qDebug(%s: %s, qPrintable(key), qPrintable(temp.join(,);value 返回每个键的最后插入, values 返回键的所有值的列表keys 为每个值重复每个键,使用uniqueKeys一次获取每个键没有 , 用 insertQMap 和QHash 也支持这个使用insertMulti休息Qt的类型定义C + +中没有定义严格跨平台类型的大小size
36、of(int) = ?对于跨平台的代码,以严格的方式定义的所有类型是很重要的ARM = 4 bytesx86 = 4 bytesIA64 = 8 bytes.取决于CPU架构,操作系统,编译器等跨平台类型TypeSizeMinimum valueMaximum valueuint81 byte0255uint162 bytes065 535uint324 bytes04 294 967 295uint648 bytes018 446 744 073 709 551 615int81 byte-128127int162 bytes-32 76832 767int324 bytes-2 147 4
37、83 6482 147 483 647int648 bytes-9 223 372 036 854 775 8089 223 372 036 854 775 807quintptr“pointer sized”n/an/aqptrdiff“pointer sized”n/an/aqrealfast real valuesn/an/a所有类型都定义在头中Qt的复杂类型Qt提供了多个复杂的类和类型QColorQBrushQRectQPointQStringQSizeQListQImageQByteArrayQPixmapQPenQFontQVariant有时候,希望能够通过一个普通的接口返回任何类
38、型QVariant类可以被视为一个联合创造一个Qt的类型联合是不可能,因为联合需要默认的构造函数变异类可以包含自定义的复杂类型,例如QColor属于QtGui,QVariant属于QtCore 一旦它们被声明,联合就不能扩展到更多类型const QVariant &data(int index);void setData(const QVariant &data, int index);数据可以是一个字符串,图片,颜色,画刷一个整数值,等使用QVariant根本类型用构造函数和 toType 函数处理非QtCore类型,如自定义类型,使用setValue 函数和模板 value 函数来处理QV
39、ariant v;QColor c(Qt:red);qDebug() Before: c; / Before: QColor(ARGB 1, 1, 0, 0) v.setValue(c);c = v.value(); / After: QColor(ARGB 1, 1, 0, 0) qDebug() After: c;QVariant v;int i = 42;qDebug() Before: i; / Before: 42v = i;i = v.toInt();qDebug() After: = 0);不必是一个QObject.QVariant与Person对象试图通过一个QVariant对
40、象传递一个Person对象失败在元类型系统中声明这一类型解决了问题class Person .;Q_DECLARE_METATYPE(Person)#endif / PERSON_Hqmetatype.h:200: error: qt_metatype_id is not a member of QMetaTypeIdQVariant与Person对象当类型注册成为一个元类型, Qt能把它存储在一个Qvariant中要求声明类型Public default constructorPublic copy constructorPublic destructorQVariant var;var.s
41、etValue(Person(Ole, 42);Person p = var.value();qDebug(%s, %d, qPrintable((), p.age();然后,它中断了.当与信号和槽工作,大局部连接是直接的直接连接时,类型可工作排队的连接,即非阻塞,异步的时候,这些类型不能工作比方跨越线程边界connect(src, SIGNAL(), dest, SLOT(), Qt:QueuedConnection);.QObject:connect: Cannot queue arguments of type Person(Make sure Person is regis
42、tered using qRegisterMetaType().)运行时的错误信息注册类型错误信息告诉我们如何解决问题qRegisterMetaType函数必须在连接建立之前被调用 (通常从main开始)int main(int argc, char *argv) qRegisterMetaType(); .文件和文件系统在跨平台中的文件和目录带来许多问题系统是否有驱动器,或只是一个根?路径是否被“/ 或 “隔开?系统在哪里存储临时文件?用户在哪里存储文档?应用程序在哪里存储?路径用QDir 类去处理路径学会用静态函数去初始化QDir d = QDir:root(); / C:/ on win
43、dowsQDir:current() / Current directoryQDir:home() / Home directoryQDir:temp() / Temporary directory/ Executable directory pathQDir(QApplication:applicationDirPath()QDir d = QDir(C:);找目录内容entryInfoList返回该目录内容的信息列表你可以添加过滤器以跳过文件或目录QFientryInfoListleInfoList infos = QDir:root().entryInfoList();foreach(c
44、onst QFileInfo &info, infos) qDebug(%s, qPrintable(info.fileName();QDir:DirsQDir:FilesQDir:NoSymLinksQDir:ReadableQDir:WritableQDir:ExecutableQDir:HiddenQDir:System以任意顺序列出文件和目录隐藏文件?系统文件?哪个文件?目录,文件或符号链接?找目录内容QDir:NameQDir:TimeQDir:SizeQDir:TypeQDir:DirsFirstQDir:DirsLastQDir:ReversedQFileInfoList inf
45、os = QDir:root().entryInfoList(QDir:Dirs, QDir:Name);foreach(const QFileInfo &info, infos) qDebug(%s, qPrintable(info.fileName();过滤器顺序排序方法 .目录在文件的前面还是后面倒序你也可以指定排序顺序从主目录根据名字排列所有目录找目录内容最后,可以添加名字过滤器QFileInfoList infos = dir.entryInfoList(QStringList() *.cpp *.h, QDir:Files, QDir:Name);foreach(const QFi
46、leInfo &info, infos) qDebug(%s, qPrintable(info.fileName();所有cpp文件和头文件QFileInfo每个 QFileInfo 对象都有许多函数absoluteFilePath 某项的完整路径isDir / isFile / isRoot 项的类型isWriteable / isReadable / isExecutable 文件的权限fileNameabsolutePathpathbaseNamecompleteSuffixsuffix当遍历时,有利于建立新的Qdir对象翻开和读取文件QFile 用来访问文件QFile f(/home/
47、john/input.txt);if (!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();每次读取160字节一次性读取所有文件写文件QFile f(/home/john/input.txt); if (!f.open(QIODevice:WriteOnly) qFatal(Could no
48、t open file);QByteArray data = createData(); f.write(data); f.close();写入文件时,用WriteOnly 模式翻开文件,用写函数向文件添加数据文件也可用ReadWrite 模式翻开Append或Truncate标志可以与写入模式相结合以追加数据到文件或截断它即去除文件以前的内容if (!f.open(QIODevice:WriteOnly|QIODevice:Append)QIODeviceQFile由QIODevice派生构造函数QTextStream和QDataStream以QIODevice指针为参数,而不是QFile指
49、针QIODevice的实现QBuffer 读写到内存缓冲 区QextSerialPort 串行(RS232) 通讯 (第三方)QAbstractSocket - TCP,SSL和UDP套接字类的基QProcess 读写进程的标准输入和输出流操作与文件读取和写入函数在许多情况下显得为难 如处理复杂类型等一个现代的方案是使用流操作Qt的提供两种流操作用于处理文本文件用于处理二进制文件格式QTextStreamQTextStream 类处理基于文本的文件读写这个类能感知编解码默认是使用区域设置,但也可以显式设置 感知行和字感知数字Results in:写入文本流使用操作符 和修饰符, 跟使用 STL 的流类似 QFile f(.);if(!f.open(QIODevice:WriteOnly) qFatal(Could not
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 协助策划团建活动方案
- 参加圣诞活动方案
- 变废为宝科普活动方案
- 参与六一活动方案
- 华联超市充值活动方案
- 医院合唱比赛活动方案
- 室内装修预算控制方案范文
- 部编语文八年级上册教学方案优化计划
- 2025-2030中国电子竞技产业生态发展及商业价值评估报告
- 2025至2030全球及中国注册会计师及管理咨询服务行业发展趋势分析与未来投资战略咨询研究报告
- 【北师大版】2024-2025学年一年级数学下册教学计划(及进度表)
- 商业安全培训
- 老年性痴呆病人的护理与管理
- 糖尿病足护理疑难病例讨论
- 草原草场承包合同
- 广西河池市2023-2024学年高二下学期7月期末考试 英语 含解析
- 《中医推拿按摩教程》课件
- 数字化赋能城乡融合发展
- 心脏骤停病人的抢救与护理
- 小红书种草营销师(初级)认证考试真题试题库(含答案)
- 汽车行业智能汽车维修与保养方案
评论
0/150
提交评论