Parallele Filter- und Filter-Reduce-Verarbeitung
Die Funktionen QtConcurrent::filter(), QtConcurrent::filtered() und QtConcurrent::filteredReduced() filtern Elemente in einer Sequenz, wie beispielsweise einer „ QList “, parallel. QtConcurrent::filter() verändert eine Sequenz an Ort und Stelle, QtConcurrent::filtered() gibt eine neue Sequenz zurück, die den gefilterten Inhalt enthält, und QtConcurrent::filteredReduced() gibt ein einzelnes Ergebnis zurück.
Diese Funktionen sind Teil des Qt Concurrent Frameworks.
Jede der oben genannten Funktionen verfügt über eine blockierende Variante, die anstelle einer „ QFuture “ das Endergebnis zurückgibt. Sie werden auf dieselbe Weise verwendet wie die asynchronen Varianten.
QStringList strings = ...;
// each call blocks until the entire operation is finished
QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strings, allLowerCase);
QtConcurrent::blockingFilter(strings, allLowerCase);
QSet<QString> dictionary = QtConcurrent::blockingFilteredReduced(strings, allLowerCase, addToDictionary);Beachten Sie, dass es sich bei den oben genannten Ergebnistypen nicht um „ QFuture “-Objekte handelt, sondern um echte Ergebnistypen (in diesem Fall „ QStringList “ und „ QSet “ <QString>).
Includes optimieren
Wenn Sie den Header „ <QtConcurrent> “ einbinden, werden das gesamte Modul „ Qt Concurrent “ sowie das gesamte Modul „ Qt Core “ eingebunden, was zu längeren Kompilierungszeiten und größeren Binärdateien führen kann. Um die Funktionen „ QtConcurrent::filter()“, „ QtConcurrent::filtered()“ und „ QtConcurrent::filteredReduced()“ zu verwenden, können Sie einen spezifischeren Header einbinden:
#include <QtConcurrentFilter>Paralleler Filter
QtConcurrent::filtered() nimmt eine Eingabesequenz und eine Filterfunktion entgegen. Diese Filterfunktion wird dann für jedes Element der Sequenz aufgerufen, und es wird eine neue Sequenz zurückgegeben, die die gefilterten Werte enthält.
Die Filterfunktion muss folgende Form haben:
bool function(const T &t);T muss mit dem in der Sequenz gespeicherten Typ übereinstimmen. Die Funktion gibt „ true “ zurück, wenn das Element beibehalten werden soll, und „false“, wenn es verworfen werden soll.
Dieses Beispiel zeigt, wie man Zeichenfolgen, die ausschließlich aus Kleinbuchstaben bestehen, aus einem ` QStringList` beibehält:
bool allLowerCase(const QString &string)
{
return string.lowered() == string;
}
QStringList strings = ...;
QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings, allLowerCase);Die Ergebnisse des Filters werden über ` QFuture` bereitgestellt. Weitere Informationen zur Verwendung von ` QFuture ` in Ihren Anwendungen finden Sie in der Dokumentation unter QFuture und QFutureWatcher.
Wenn Sie eine Sequenz an Ort und Stelle ändern möchten, verwenden Sie QtConcurrent::filter():
QStringList strings = ...;
QFuture<void> future = QtConcurrent::filter(strings, allLowerCase);Da die Sequenz direkt geändert wird, gibt QtConcurrent::filter() keine Ergebnisse über QFuture zurück. Sie können jedoch weiterhin QFuture und QFutureWatcher verwenden, um den Status des Filters zu überwachen.
Paralleles Filtern und Fortsetzungen
Das Ergebnis des Aufrufs von `QtConcurrent::filtered()` ist ein ` QFuture `, der mehrere Ergebnisse enthält. Wenn Sie eine ` .then() `-Fortsetzung an ein solches ` QFuture` anhängen, achten Sie darauf, eine Fortsetzung zu verwenden, die ` QFuture ` als Parameter akzeptiert; andernfalls wird nur das erste Ergebnis verarbeitet:
auto keepPositive = [](int val) {
return val > 0;
};
QList<int> inputs {-1, 1, 2,-3, 5 };
auto badFuture = QtConcurrent::filtered(inputs, keepPositive)
.then([](int val) {
qDebug() << val;
});
auto goodFuture = QtConcurrent::filtered(inputs, keepPositive)
.then([](QFuture<int> f) {
for (auto r : f.results()) {
qDebug() << r;
}
});In diesem Beispiel gibt „ badFuture “ nur ein einziges Ergebnis aus, während „ goodFuture “ alle Ergebnisse ausgibt.
Paralleles Filter-Reduce
QtConcurrent::filteredReduced() ähnelt QtConcurrent::filtered(), gibt jedoch keine Sequenz mit den gefilterten Ergebnissen zurück, sondern fasst die Ergebnisse mithilfe einer Reduce-Funktion zu einem einzigen Wert zusammen.
Die Reduzierungsfunktion muss folgende Form haben:
V function(T &result, const U &intermediate)T ist der Typ des Endergebnisses, U ist der Typ der zu filternden Elemente. Beachten Sie, dass der Rückgabewert und der Rückgabetyp der Reduzierungsfunktion nicht verwendet werden.
Rufen Sie `QtConcurrent::filteredReduced()` wie folgt auf:
void addToDictionary(QSet<QString> &dictionary, const QString &string)
{
dictionary.insert(string);
}
QStringList strings = ...;
QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary);Die `reduce`-Funktion wird für jedes von der Filterfunktion beibehaltene Ergebnis einmal aufgerufen und sollte den Zwischenspeicher in die Ergebnisvariable zusammenführen. `QtConcurrent::filteredReduced()` garantiert, dass jeweils nur ein Thread die `reduce`-Funktion aufruft, sodass die Verwendung eines Mutex zum Sperren der Ergebnisvariable nicht erforderlich ist. Die Enumeration „ QtConcurrent::ReduceOptions “ bietet eine Möglichkeit, die Reihenfolge zu steuern, in der die Reduktion durchgeführt wird.
Weitere API-Funktionen
Verwendung von Iteratoren anstelle von Sequenzen
Jede der oben genannten Funktionen verfügt über eine Variante, die anstelle einer Sequenz einen Iteratorbereich akzeptiert. Sie werden genauso verwendet wie die Sequenzvarianten:
QStringList strings = ...;
QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings.constBegin(), strings.constEnd(), allLowerCase);
// filter in-place only works on non-const iterators
QFuture<void> future = QtConcurrent::filter(strings.begin(), strings.end(), allLowerCase);
QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary);Verwendung von Mitgliedsfunktionen
QtConcurrent::filter(), QtConcurrent::filtered() und QtConcurrent::filteredReduced() akzeptieren Zeiger auf Mitgliedsfunktionen. Der Typ der Mitgliedsfunktionsklasse muss mit dem in der Sequenz gespeicherten Typ übereinstimmen:
// Nur Bilder mit einem Alphakanal behalten
QList<QImage> images =...;
QFuture<void> alphaImages = QtConcurrent::filter(images,&QImage::hasAlphaChannel);
// Graustufenbilder abrufen
QList<QImage> images =...;
QFuture<QImage> graustufenBilder = QtConcurrent::filtered(images,&QImage::isGrayscale);
// eine Menge aller druckbaren Zeichen erstellen
QList<QChar> Zeichen =...;
QFuture<QSet<QChar>> set = QtConcurrent::filteredReduced(Zeichen, qOverload<>(&QChar::isPrint),
qOverload<const QChar&>(&QSet<QChar>::insert));Beachten Sie die Verwendung von „ qOverload “. Dies ist erforderlich, um die Mehrdeutigkeit bei Methoden zu beseitigen, die mehrere Überladungen aufweisen.
Beachten Sie außerdem, dass Sie bei der Verwendung von `QtConcurrent::filteredReduced()` normale Funktionen und Member-Funktionen beliebig miteinander kombinieren können:
// Mit QtConcurrent::filteredReduced() können normale Funktionen und Mitgliedsfunktionen gemischt werden
// Erstelle ein Wörterbuch mit allen Strings in Kleinbuchstaben
extern bool allLowerCase(const QString&string);
QStringList strings =...;
QFuture<QSet<QString>> lowerCase = QtConcurrent::filteredReduced(strings, allLowerCase,
qOverload<const QString&>(&QSet<QString>::insert));
// Eine Collage aus allen Graustufenbildern erstellen
extern void addToCollage(QImage &collage, const QImage &grayscaleImage);
QList<QImage> images =...;
QFuture<QImage> Collage = QtConcurrent::filteredReduced(images,&QImage::isGrayscale, addToCollage);Verwendung von Funktionsobjekten
QtConcurrent::filter(), QtConcurrent::filtered() und QtConcurrent::filteredReduced() akzeptieren Funktionsobjekte als Filterfunktion. Diese Funktionsobjekte können verwendet werden, um einem Funktionsaufruf einen Zustand hinzuzufügen:
struct StartsWith
{
StartsWith(const QString &string)
: m_string(string) { }
bool operator()(const QString &testString)
{
return testString.startsWith(m_string);
}
QString m_string;
};
QList<QString> strings = ...;
QFuture<QString> fooString = QtConcurrent::filtered(strings, StartsWith(QLatin1String("Foo")));Funktionsobjekte werden auch für die Reduzierungsfunktion unterstützt:
struct StringTransform
{
void operator()(QString &result, const QString &value);
};
QFuture<QString> fooString =
QtConcurrent::filteredReduced(strings, StartsWith(QLatin1String("Foo")), StringTransform());Verwendung von Lambda-Ausdrücken
QtConcurrent::filter(), QtConcurrent::filtered() und QtConcurrent::filteredReduced() akzeptieren Lambda-Ausdrücke für die Filter- und Reduce-Funktion:
// keep only even integers
QList<int> list { 1, 2, 3, 4 };
QtConcurrent::blockingFilter(list, [](int n) { return (n & 1) == 0; });
// retrieve only even integers
QList<int> list2 { 1, 2, 3, 4 };
QFuture<int> future = QtConcurrent::filtered(list2, [](int x) {
return (x & 1) == 0;
});
QList<int> results = future.results();
// add up all even integers
QList<int> list3 { 1, 2, 3, 4 };
QFuture<int> sum = QtConcurrent::filteredReduced(list3,
[](int x) {
return (x & 1) == 0;
},
[](int &sum, int x) {
sum += x;
}
);Bei der Verwendung von QtConcurrent::filteredReduced() oder QtConcurrent::blockingFilteredReduced() können Sie normale Funktionen, Member-Funktionen und Lambda-Ausdrücke beliebig miteinander kombinieren.
void intSumReduce(int &sum, int x)
{
sum += x;
}
QList<int> list { 1, 2, 3, 4 };
QFuture<int> sum = QtConcurrent::filteredReduced(list,
[] (int x) {
return (x & 1) == 0;
},
intSumReduce
);Sie können auch ein Lambda als Reduce-Objekt übergeben:
bool keepEvenIntegers(int x)
{
return (x & 1) == 0;
}
QList<int> list { 1, 2, 3, 4 };
QFuture<int> sum = QtConcurrent::filteredReduced(list,
keepEvenIntegers,
[](int &sum, int x) {
sum += x;
}
);Funktionen mit mehreren Argumenten umschließen
Wenn Sie eine Filterfunktion verwenden möchten, die mehr als ein Argument akzeptiert, können Sie eine Lambda-Funktion oder „ std::bind() “ nutzen, um sie in eine Funktion umzuwandeln, die ein Argument akzeptiert.
Als Beispiel verwenden wir „ QString::contains()“:
bool QString::contains(const QRegularExpression ®exp) const;QString::contains() nimmt zwei Argumente entgegen (einschließlich des „this“-Zeigers) und kann nicht direkt mit QtConcurrent::filtered() verwendet werden, da QtConcurrent::filtered() eine Funktion erwartet, die ein Argument entgegennimmt. Um ` QString::contains()` mit `QtConcurrent::filtered()` zu verwenden, müssen wir einen Wert für das Argument `regexp` angeben:
QStringList strings = ...;
QFuture<QString> future = QtConcurrent::filtered(list, [](const QString &str) {
return str.contains(QRegularExpression("^\\S+$")); // matches strings without whitespace
});© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.