警告
本节包含从C++自动翻译到Python的代码片段,可能包含错误。
Qt中的Java风格迭代器¶
用于Qt容器的Java风格迭代器。
Java风格迭代器¶
对于每个容器类,有两种Java风格的迭代器数据类型:一种提供只读访问,另一种提供读写访问。
注意
新代码应使用STL风格的迭代器,因为这些迭代器更高效,并且可以与Qt和STL的通用算法一起使用。
容器 |
只读迭代器 |
读写迭代器 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
在这次讨论中,我们将专注于QList和QMap。QSet的迭代器类型与QList的迭代器具有完全相同的接口;同样,QHash的迭代器类型与QMap的迭代器具有相同的接口。
与STL风格的迭代器不同,Java风格的迭代器指向项目之间而不是直接指向项目。因此,它们要么指向容器的开始(在第一个项目之前),要么指向容器的末尾(在最后一个项目之后),要么指向两个项目之间。下图显示了包含四个项目的列表中有效迭代器位置的红箭头:
这是一个典型的循环,用于按顺序遍历QList < QString >的所有元素:
list = {"A", "B", "C", "D"} i = QListIterator(list) while i.hasNext(): s = i.next()
它的工作原理如下:要迭代的QList被传递给QListIterator构造函数。此时,迭代器位于列表中的第一个项目之前(在项目“A”之前)。然后我们调用hasNext()来检查迭代器后面是否有项目。如果有,我们调用next()来跳过那个项目。next()函数返回它跳过的项目。对于QList < QString >,该项目是QString类型的。
以下是如何在QList中向后迭代:
i = QListIterator(list) i.toBack() while i.hasPrevious(): s = i.previous()
代码与向前迭代是对称的,除了我们首先调用toBack()将迭代器移动到列表中的最后一个项目之后。
下图展示了调用next()和previous()对迭代器的影响:
下表总结了QListIterator API:
函数
行为
toFront()将迭代器移动到列表的前面(在第一个项目之前)
toBack()将迭代器移动到列表的末尾(在最后一项之后)
hasNext()如果迭代器不在列表的末尾,则返回
true
next()返回下一个项目并将迭代器前进一个位置
peekNext()返回下一个项目而不移动迭代器
hasPrevious()如果迭代器不在列表的前面,则返回
true
previous()返回前一个项目并将迭代器向后移动一个位置
peekPrevious()返回前一个项目而不移动迭代器
QListIterator 在迭代时没有提供插入或删除列表项的功能。要实现这一点,你必须使用 QMutableListIterator。以下是一个使用 QMutableListIterator 从 QList
i = QMutableListIterator(list) while i.hasNext(): if i.next() % 2 != 0: i.remove()
循环中的next()调用每次都会执行。它会跳过列表中的下一个项目。remove()函数会从列表中移除我们跳过的最后一个项目。调用remove()不会使迭代器失效,因此可以安全地继续使用它。这在向后迭代时同样有效:
i = QMutableListIterator(list) i.toBack() while i.hasPrevious(): if i.previous() % 2 != 0: i.remove()
如果我们只想修改现有项的值,我们可以使用setValue()。在下面的代码中,我们将任何大于128的值替换为128:
i = QMutableListIterator(list) while i.hasNext(): if i.next() > 128: i.setValue(128)
就像remove()一样,setValue()操作的是我们跳过的最后一个项目。如果我们向前迭代,这是迭代器之前的项目;如果我们向后迭代,这是迭代器之后的项目。
next() 函数返回列表中项目的非常量引用。对于简单的操作,我们甚至不需要 setValue() :
i = QMutableListIterator(list) while i.hasNext(): i.next() *= 2
如上所述,QSet 的迭代器类与 QList 的API完全相同。我们现在将转向 QMapIterator,它有些不同,因为它迭代的是(键,值)对。
与 QListIterator 类似,QMapIterator 提供了 toFront()、toBack()、hasNext()、next()、peekNext()、hasPrevious()、previous() 和 peekPrevious()。通过调用 next()、peekNext()、previous() 或 peekPrevious() 返回的对象上的 key() 和 value() 来提取键和值组件。
以下示例删除了所有首都名称以“City”结尾的(首都,国家)对:
QMap<QString, QString> map = { {"Paris", "France"}, {"Guatemala City", "Guatemala"}, {"Mexico City", "Mexico"}, {"Moscow", "Russia"} ... QString> = QMutableMapIterator<QString,(map) while i.hasNext(): if i.next().key().endsWith("City"): i.remove()
QMapIterator 还提供了一个 key() 和一个 value() 函数,这些函数直接在迭代器上操作,并返回迭代器跳过的最后一个项的键和值。例如,以下代码将 QMap 的内容复制到 QHash 中:
QWidget = QMap<int,() QWidget = QHash<int,() QWidget = QMapIterator<int,(map) while i.hasNext(): i.next() hash.insert(i.key(), i.value())
如果我们想要遍历所有具有相同值的项目,我们可以使用findNext()或findPrevious()。这里有一个例子,我们删除了所有具有特定值的项目:
QWidget = QMutableMapIterator<int,(map) while i.findNext(widget): i.remove()