关于Qt的model-view部分就告一段落,今天咱们开始新的部分。或许有些朋友以为前面的部分说得很简单。对此我也没有办法,毕竟,Qt是一个很庞大的库,一时半会根本不可能穷尽全部内容,而且我也有不少东西不知道,有时候也必须去查找资料才能明白。
今天开始的部分是关于Qt提供的一些通用算法。这部份内容来自C++ GUI Programming with Qt 4, 2nd Edition。
<QtAlgorithms>提供了一系列通用的模板函数,用于实现容器上面的基本算法。这部分算法不少依赖于STL风格的遍历器(还记得前面曾经说过的Java风格的遍历器和STL风格的遍历器吗?)。实际上,C++ STL也提供了不少通用算法,包含在
<algorithm>头文件内。这部分算法对于Qt容器一样也是适用的。所以,若是你想使用的算法在Qt的<QtAlgorithms>头文件中没有包含,那么就可使用STL的算法代替,这并不会产生什么冲突。这里咱们来讲几个Qt中的通用算法。虽然这些算法都是很简单的,可是,库函数每每会比本身编写的更有效率,所以仍是推荐使用系统提供的函数的。
首先是qFind()函数。qFind()函数会在容器中查找一个特定的值。它的参数中有一个起始位置和终止位置,若是被查找的元素存在,函数返回第一个匹配项的位置,不然则返回终止位置。注意,咱们这里说的“位置”,其实是STL风格的遍历器。咱们知道,使用STL风格遍历器是能够反映一个位置的。例以下面的例子,i的值将是list.begin() + 1,而j会是list.end():

QStringList list;

list <<
"Emma" <<
"Karl" <<
"James" <<
"Mariette";

QStringList::iterator i = qFind(list.begin(), list.end(),
"Karl");

QStringList::iterator j = qFind(list.begin(), list.end(),
"Petra");
qBinaryFind()的行为很像qFind(),所不一样的是,
qBinaryFind()是二分查找算法,它只适用于查找排序以后的集合,而qFind()则是标准的线性查找。一般,二分查找法使用条件更为苛刻,可是效率也会更高。
qFill()会使用给定值对容器进行填充。例如:

QLinkedList<
int> list(10);

qFill(list.begin(), list.end(), 1009);
正如其余基于遍历器的算法同样,qFill()也能够针对容器的一部分进行操做,例以下面的代码将会把vector的前5位设置成1009,而最后5位设置为2013:

QVector<
int> vect(10);

qFill(vect.begin(), vect.begin() + 5, 1009);

qFill(vect.end() - 5, vect.end(), 2013);
qCopy()算法能够实现将一个容器中的元素复制到另外一个容器,例如:
qCopy()也能够用于同一容器中的元素的复制。qCopy()操做成功的关键是源容器和目的容器的范围不会发生溢出。例如以下代码,咱们将把一个列表的最后两个元素复制给前两个元素:
qCopy(list.begin(), list.begin() + 2, list.end() - 2);
qSort()实现了容器元素的递增排序,使用起来也很简单:
qSort(list.begin(), list.end());
默认状况下,qSort()将使用 < 运算符进行元素的比较。这暗示若是须要的话,你必须定义 < 运算符。若是须要按照递减排序,须要将qGreater<T>()看成第三个参数传给qSort()函数。例如:
qSort(list.begin(), list.end(), qGreater<int>());
注意,这里的T其实是容器的泛型类型。实际上,咱们能够利用第三个参数对排序进行定义。例如,咱们自定义的数据类型中有一个大小写不敏感的QString的小于比较函数:
bool insensitiveLessThan(const QString &str1, const QString &str2)
{
return str1.toLower() < str2.toLower();
}
那么,咱们能够这样使用qSort()从而能够利用这个函数:
QStringList list;
// ...
qSort(list.begin(), list.end(), insensitiveLessThan);
qStableSort()函数相似与qSort(),所不一样之处在于它是稳定排序。稳定排序是算法设计上的一个名词,意思是,在排序过程当中,若是有两个元素相等,那么在排序结果中这两个元素的前后顺序同排序前的原始顺序是一致的。举个例子,对于一个序列:a1, a5, a32, a31, a4,它们的大小顺序是a1 < a31 = a32 < a4 < a5,那么稳定排序以后的结果应该是 a1, a32, a31, a4, a5,也就是相等的元素在排序结果中出现的顺序和原始顺序是一致的。稳定排序在某些场合是颇有用的,好比,如今有一份按照学号排序的学生成绩单。你想按照成绩高低从新进行排序,对于成绩同样的学生,仍是遵循原来的学号顺序。这时候就要稳定排序了。
qDeleteAll()函数将对容器中存储的全部指针进行delete操做。这个函数仅在容器元素是指针的情形下才适用。执行过这个函数以后,容器中的指针均被执行了delete运算,可是这些指针依然被存储在容器中,成为野指针,你须要调用容器的clear()函数来避免这些指针的误用:
qDeleteAll(list);
list.clear();
qSwap()函数能够交换两个元素的位置。例如:
int x1 = line.x1();
int x2 = line.x2();
if (x1 > x2)
qSwap(x1, x2);
最后,在<QtGlobal>头文件中,也定义了几个有用的函数。这个头文件被其余全部的头文件include了,所以你不须要显式的include这个头文件了。
在这个头文件中有这么几个函数:qAbs()返回参数的绝对值,qMin()和qMax()则返回两个值的最大值和最小值。