qt核心编程.pdf
《qt核心编程.pdf》由会员分享,可在线阅读,更多相关《qt核心编程.pdf(29页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、11Qt 模板库Qt 模板库(QT Template Library 简称 QTL)是一套提供对象容器的模板。如果你的编译器没有适当的STL(标准模板库)可用,QTL将被代替使用。QTL 提供了对象的链表、对象的矢量(动态数组)、从一个类型到另一个类型的映射(或称为字典)和相关的迭代器和算法。一个容器是包含和管理其它对象的一个对 象,并且提供迭代器对被包含的对 象进行访问。Qt 模板类说明如表 2。表 2Qt 模板类说明模板类名称说明QMap提供基于值的一个字典的模板类QMapConstIteratorQMap的常量迭代器QMapIteratorQMap的迭代器QPair提供基于值的一对元素的
2、模板类QValueList提供基于值的一个双向链表的模板类QValueListConstIteratorQValueList的常量迭代器QValueListIteratorQValueList的迭代器QValueStack提供基于值的一个堆栈模板类QValueVector提供基于值的一个动态数组模板类QTL 类的命名约定与其他 Qt 类一致(比如,count()、isEmpty())。它们还提供额外的函数来兼容STL 算法,比如size()和empty()。可以像使用STL 的函数 map一样来使用它们。与STL 相比,QTL仅仅包含了STL 容器应用程序接口的最重要的特性,没有平台差异,通常
3、要慢一些并且经常扩展为更少的对象代码。如果你不想拷贝存储对象,你最好使用QPtrCollection 及派生类。它们就是被设计用来处理各种类指针的。QObject 没有拷贝 构造函数,因此 QObject 不能作为一个值使用。但可以存储指向 QObject 的指针到QValueList。当然,直接使用 QPtrList 更好。QPtrList 像所有其它的基于 QPtrCollection 的容器一样,提供了比速度优化了、基于值的容器更多健全的检查。如果你有一些使用值的对象,并且在你的目标平台没有可用的 STL,Qt 模板库就可以替代它。使用值的对象至少需要一个拷贝构造函数、一个赋值操作符和一
4、个默认构造函数(如:一个没有任何参数的构造函数)。注意一个快速的拷贝构造函数对于容器的高性能是关键的,因为许多拷贝操作将会发生。如果你想排序你的数据,你必须在你的数据类中实现operator()。Qt 模板库是为高性能而设计,迭代器是非常快的。为了实现这样的性能,Qt 模板库比基于QPtrCollection 的 集合类做更少的错误 检查。一个 QTL 容器,例如:QTL容器没有跟踪任何相关的迭代器。这样在诸如删除条目时没有执行有效性检查,但它提供了很好的执行性能。11.1 迭代器(Iterators)Qt 模板库打交道的是值对象,而不是指针对象。迭代器是最好的遍历容器方法。遍历一个容器可使用
5、像下面的循环:typedef QValueList List;List l;for(List:Iterator it=l.begin();it!=l.end();+it)printf(Number is%in,*it);begin()返回第一个元素的迭代器,end()返回的是最后一个元素之后的一个迭代器。end()标明的是一个无效 的位置,它永远不能被解除引用。它 只是任何一次迭代的终止条件,迭代可以从 begin()或 end()开始。同样的概念也适用于其它容器类,例如,用于QMap 和 QValueVector 的迭代方法如下:typedef QMap Map;Map map;for(Ma
6、p:iterator it=map.begin();it!=map.end();+it)printf(Key=%s Data=%sn,it.key().ascii(),it.data().ascii();typedef QValueVector Vector;Vector vec;for(Vector:iterator it=vec.begin();it!=vec.end();+it)printf(Data=%dn,*it);11.2 算法Qt 模板库定义了大量操作容器的算法。这些算法用模板库函数实现,还提供了有迭代器的容器的通用代码。例如:qHeapSort()和 qBubbleSort()
7、提供了著名的堆排序和冒泡排序算法。你可以象下面这样使用它们:typedef QValueList List;List l;l 42 100 1234 12 8;qHeapSort(l);List l2;l2 42 100 1234 12 8;List:Iterator b=l2.find(100);List:Iterator e=l2.find(8);qHeapSort(b,e);double arr=3.2,5.6,8.9;qHeapSort(arr,arr+3);第一个例子对整个列表排序。第二个例子对两个迭代器之间的所有元素排序,即 100、1234和 12。第三个例子表明迭代器是作为指针
8、使用的。一些常用的模板函数说明如下:(1)函数 qSwap()用来交换两个变量的值,例如:QString second(Einstein);QString name(Albert);qSwap(second,name);(2)函数 qCount()用于统计容器中一个值出现的次数。例如:QValueList l;l.push_back(1);/放入 1到 l 链表中 l.push_back(1);l.push_back(1);l.push_back(2);int c=0;qCount(l.begin(),l.end(),1,c);/统计 1 的个数 c,c=3(3)函数 qFind()用于查找容
9、器中一个值的第一次出现位置。例如:QValueList l;l.push_back(1);l.push_back(1);l.push_back(1);l.push_back(2);/查找 2所在的位置 QValueListIterator it=qFind(l.begin(),l.end(),2);(4)函数 qFill()用于将一个值拷贝填充到一个范围。例如:QValueVector v(3);qFill(v.begin(),v.end(),99);/将 99 填充整个 v 数组,v包含 99,99,99(5)函数 qEqual()用来比较两个范围的元素是否相等,两个范围的元素个数不一定相等
10、。只要第一个范围的元素与第二个范围的对应元素都相等时,就认为这两个范围相等。例如:QValueVector v1(3);v10=1;v12=2;v13=3;QValueVector v2(5);v10=1;v12=2;v13=3;v14=4;v15=5;bool b=qEqual(v1.begin(),v2.end(),v2.begin();/b=TRUE(6)函数 qCopy()用于拷贝一个范围的元素到输出迭代器,例如:QValueList l;l.push_back(100);l.push_back(200);l.push_back(300);QTextOStream str(stdout
11、);/拷贝 l中所有元素到输出迭代器 QTextOStreamIterator qCopy(l.begin(),l.end(),QTextOStreamIterator(str);(7)函数 qCopyBackward()用于拷贝一个容器或者它的一部分到一个输出迭代器,拷贝的次序是从后面开始,例如:QValueVector vec(3);vec.push_back(100);vec.push_back(200);vec.push_back(300);QValueVector another;/“another”包含的是按倒序排列的(300、200、100)。qCopyBackward(vec.
12、begin(),vec.end(),another.begin();如果你写了新的算法,请考虑把它们写成模板函数,这样就可以使它们能够用在尽可能多的容器上了。在上一个例子中,你可以很容易地使用qCopy()打印出一个标准 C+数组,方法列出如下:int arr=100,200,300;QTextOStream str(stdout);qCopy(arr,arr+3,QTextOStreamIterator(str);11.3 数据流串行化所有提到的容器(如:QValueList、QStringList、QValueStack 和 QMap等)都可被相应的流操作符串行化。下面是一个例子。QDat
13、aStream str(.);QValueList l;/在这里填充这个列表 str l;容器还能象下面这样被再一次读入:QValueList l;str l;12集合类一个集合类是装有多个条目的容器,每个条目是某种数据结构,集合类能执行对容器中的条目的插入、删除及查找等操作。Qt 有几个基于值和基于指针的集合类。基于指针的集合类使用指向条目的指针来工作,而基于值的集合类存储着它们条目的拷贝。基于值的集合类类似于 STL 容器类,能和 STL算法和容器一起使用。基于值的集合类说明如表4 所示:表4基于值的集合类表类名称说明QValueList基于值的链表QValueVector基于值的矢量结构
14、QValueStack基于值的栈结构QMap基于值的字典结构基于指针的集合类说明如表5 所示:表 5基于指针的集合类表类名称说明QCache和QIntCacheLRU(least recently used)缓存结构。QDict、QIntDict和QPtrDict字典结构。QPtrList双向链接的链表结构。QPtrQueueFIFO 先进先出(first in,first out)队列结构。QPtrStackLIFO后进先出(last in,first out)栈结构。QPtrVector矢量结构。QMemArray 是一个例外,它既不是基于指针也不是基于值,而是基于内存的结构。用于在有简单
15、数据结构的数组中使用QMemArray 效率最高,QMemArray 在拷贝和数组元素比较时使用位逻辑运算符操作。这些类中有一些具有迭代器,迭代器是遍历集合类中的条目的类。在 Qt 模板库里,基于值的集合和算法集成在一起。下面讨论基于指针的容器。12.1 基于指针的容器的结构基于指针的容器有4 个内部基类(QGCache,QGDict,QGList 和 QGVector)操作 void 类型指针。通过增加/删除条目指针,一个由这4 个类组成的薄模板层实现了实际的集合。允许Qt 的模板类的策略使得在空间上很经济(实现这些模板类仅增加了对基类的内联调用),而且还不影响执行效率。示例:QPtrLis
16、t 使用下面的例子说明了如何存储Employee 条目到一个链表,并将它们以相反的次序打印出来。#include#include#include class Employeepublic:Employee(const char*name,int salary)n=name;s=salary;const char*name()const return n;int salary()const return s;private:QString n;int s;int main()QPtrList list;/指向 Employee 的指针链表。list.setAutoDelete(TRUE);/当链
17、表条目被移动时,删除条目。list.append(new Employee(Bill,50000);/链表追加新的对象。list.append(new Employee(Steve,80000);list.append(new Employee(Ron,60000);QPtrListIterator it(list);/遍历Employee 链表。for(it.toLast();it.current();-it)/从尾向头遍历。Employee*emp=it.current();printf(%s earns%dn,emp-name(),emp-salary();return 0;程序运行结果
18、如下:Ron earns 60000Steve earns 80000Bill earns 5000012.2 管理集合条目所有基于指针的集合继承了QPtrCollection 基类。这个类仅知道集合中的条目个数和删除策略。当集合中的条目被移去时,缺省时它们不被删除。QPtrCollection:setAutoDelete()定义了删除策略。在上述QPtrList 使用示例子,我们激活了自动删除功能来进行链表删除。当插入一个条目到一个集合时,仅指针被拷贝,而不是拷贝条目本身。这称为浅拷贝。当插入一个条目时,拷贝所有条目的数组到集合中也是可能的,这称为深拷贝。所有的集合类函数在插入条目时调用虚拟
19、函数 QPtrCollection:newItem()。如果你想进行深拷贝,你需要重载它。当从一个链表中移去一个条目时,调用虚拟函数 QPtrCollection:deleteItem()。如果自动删除功能被激活,在所有集合类中的缺省实现函数被调用来删除条目。基于指针的集合类,如:QPtrList,定义了指向对象的指针集合。我们在这里只讨论 QPtrList 类,其它的基于指针的集合类和所有集合类迭代器都有同样的使用方法。模板实例化方法如下:QPtrList list;在这个例子中,条目的类或类型是Employee,它必须在链表定义之前被定义。例如:class Employee .;QPtrL
20、ist list;12.3 迭代器(Iterators)QPtrListIterator 能在链表被修改的同时非常安全的遍历链表。在同一个集合上,多个迭代器能独立地工作。QPtrList 有一个指向所有迭代器的内部链表,这些迭代器当前操作链表。当一个链表条目被移去时,链表更新所有的指向这个条目的迭代器。QDict 和 QCache集合没有遍历函数。为了遍历集合,你必须使用 QDictIterator 或 QCacheIterator。Qt 预定义的集合类有字符串链表:QStrList,QStrIList(在 qstrlist.h 中)和 QStringList(在 qstringlist.h
21、中)。在绝大多数情况下你将选择QStringList,它是一个共享的 QString Unicode 字符串的值链表。QPtrStrList 和 QPtrStrIList 仅存储字符指针,而不是字符串本身。基于指针的集合类和相关的迭代器类说明如表 4。表 4基于指针的集合类和相关的迭代器类列表QAsciiCache基于char*keys 的缓存的模板类。QAsciiCacheIteratorQAsciiCache集合的迭代器。QAsciiDict基于char*keys 的字典的模板类。QAsciiDictIteratorQAsciiDict集合的迭代器。QBitArrayBit位数组。QBit
22、Val与 QBitArray 一起用的内部类QBuffer在QByteArray上操作的I/O设备。QByteArray字节数组QCache基于QString keys的模板类。QCacheIteratorQCache集合的迭代器。QCStringC语言中0结尾的字符数组(char*)。QDict基于QString keys 的字典的模板类。QDictIteratorQDict collections的迭代器。QIntCache基于long keys 的缓存的模板类。QIntCacheIteratorQIntCache集合的迭代器。QIntDict基于long keys 的字典的模板类。QIn
23、tDictIteratorQIntDict集合的迭代器。QObjectListQObjects的QPtrList链表。QObjectListItQObjectLists的迭代器。QPtrCollection大多数基于指针的Qt集合的基类。QPtrDict基于void*keys的字典的模板类。QPtrDictIteratorQPtrDict的迭代器。QPtrList双向链表的模板类。QPtrListIteratorQPtrList集合的迭代器。QPtrQueue一个队列的模板类。QStrIList对于大小写敏感的char*双向链接的链表。QStrListchar*双向链接的链表。13 Qt 线程
24、Qt 对线程提供了支持,它引入了一些基本与平台无关的线程类、线程安全传递事件的方式和全局 Qt 库互斥量允许你从不同的线程调用Qt 的方法。Qt 中与线程应用相关的类如表 6 所示。表6Qt 中与线程相关的类QMutex线程之间的互斥锁QSemaphore整数信号量QThread与平台无关的线程QWaitCondition线程之间允许等待/唤醒的条件使用线程需要Qt 提供相应的线程库的支持,因此,在编译安装 Qt 时,需要加上线程支持选项。当在Windows 操作系统上编译Qt 时,线程支持是在一些编译器上的一个选项。在 Windows 操作系统上编译应用程序时,通过在qconfig.h 文件
25、中增加一个选项来解决来解决这个问题。在Mac OS X 和 Unix 上编译Qt 时,你应在运行 configure 脚本时添加-thread选项。在Unix 平台上,多线程 程序必须用特殊的线程支持库连接,多线 程程序必须连接线程支持库libqt-mt,而不是标准的 Qt 库。编译应用程序时,你应该使用宏定义QT_THREAD_SUPPORT 来编译(如:编译 时使用-DQT_THREAD_SUPPORT)。13.1 线程类 QThread 在 Qt 中提供了QThread 线程类,它提供了创建一个新线程的方法。线程通过重载 QThread:run()函数开始执行的,这一点与Java 中的线
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- qt 核心 编程
限制150内