Filtrage et filtrage-réduction simultanés
Les fonctions QtConcurrent::filter(), QtConcurrent::filtered() et QtConcurrent::filteredReduced() filtrent en parallèle les éléments d'une séquence, telle qu'une QList. QtConcurrent::filter() modifie une séquence sur place, QtConcurrent::filtered() renvoie une nouvelle séquence contenant le contenu filtré, et QtConcurrent::filteredReduced() renvoie un résultat unique.
Ces fonctions font partie du Qt Concurrent framework.
Chacune des fonctions ci-dessus dispose d'une variante bloquante qui renvoie le résultat final au lieu d'une QFuture. Vous les utilisez de la même manière que les variantes asynchrones.
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);Notez que les types de résultat ci-dessus ne sont pas des objets ` QFuture `, mais de véritables types de résultat (dans ce cas, ` QStringList ` et ` QSet<QString>`).
Optimisation des inclusions
Si vous incluez l’en-tête <QtConcurrent>, l’intégralité du module Qt Concurrent ainsi que l’intégralité du module Qt Core seront incluses, ce qui peut augmenter les temps de compilation et la taille des binaires. Pour utiliser les fonctions QtConcurrent::filter(), QtConcurrent::filtered() et QtConcurrent::filteredReduced(), vous pouvez inclure un en-tête plus spécifique :
#include <QtConcurrentFilter>Filtre concurrent
QtConcurrent::filtered() prend en paramètre une séquence d’entrée et une fonction de filtrage. Cette fonction de filtrage est ensuite appelée pour chaque élément de la séquence, et une nouvelle séquence contenant les valeurs filtrées est renvoyée.
La fonction de filtrage doit être de la forme suivante :
bool function(const T &t);T doit correspondre au type stocké dans la séquence. La fonction renvoie « true » si l'élément doit être conservé, et «false» s'il doit être écarté.
Cet exemple montre comment conserver les chaînes de caractères entièrement en minuscules à partir d’ QStringList:
bool allLowerCase(const QString &string)
{
return string.lowered() == string;
}
QStringList strings = ...;
QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings, allLowerCase);Les résultats du filtrage sont disponibles via ` QFuture`. Consultez la documentation QFuture et QFutureWatcher pour plus d’informations sur l’utilisation de ` QFuture ` dans vos applications.
Si vous souhaitez modifier une séquence sur place, utilisez QtConcurrent::filter() :
QStringList strings = ...;
QFuture<void> future = QtConcurrent::filter(strings, allLowerCase);Comme la séquence est modifiée sur place, QtConcurrent::filter() ne renvoie aucun résultat via QFuture. Vous pouvez toutefois continuer à utiliser QFuture et QFutureWatcher pour surveiller l’état du filtre.
Filtrage concurrent et continuations
Le résultat de l'appel à QtConcurrent::filtered() est un QFuture contenant plusieurs résultats. Lorsque vous associez une continuation de type .then() à un tel QFuture, veillez à utiliser une continuation qui prend QFuture en paramètre, sinon seul le premier résultat sera traité :
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;
}
});Dans cet exemple, badFuture n'affichera qu'un seul résultat, tandis que goodFuture affichera tous les résultats.
Filtre-réduction concurrente
QtConcurrent::filteredReduced() est similaire à QtConcurrent::filtered(), mais au lieu de renvoyer une séquence contenant les résultats filtrés, les résultats sont combinés en une seule valeur à l'aide d'une fonction de réduction.
La fonction de réduction doit être de la forme suivante :
V function(T &result, const U &intermediate)T correspond au type du résultat final, U au type des éléments filtrés. Notez que la valeur de retour et le type de retour de la fonction de réduction ne sont pas utilisés.
Appelez QtConcurrent::filteredReduced() comme suit :
void addToDictionary(QSet<QString> &dictionary, const QString &string)
{
dictionary.insert(string);
}
QStringList strings = ...;
QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary);La fonction `reduce` sera appelée une fois pour chaque résultat conservé par la fonction de filtrage, et devra fusionner la valeur intermédiaire dans la variable `result`. `QtConcurrent::filteredReduced()` garantit qu’un seul thread appellera `reduce` à la fois ; il n’est donc pas nécessaire d’utiliser un mutex pour verrouiller la variable `result`. L'énumération ` QtConcurrent::ReduceOptions ` permet de contrôler l'ordre dans lequel la réduction est effectuée.
Fonctionnalités supplémentaires de l’API
Utilisation d’itérateurs à la place de séquences
Chacune des fonctions ci-dessus dispose d'une variante qui prend une plage d'itérateurs à la place d'une séquence. Vous les utilisez de la même manière que les variantes de séquence :
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);Utilisation des fonctions membres
QtConcurrent::filter(), QtConcurrent::filtered() et QtConcurrent::filteredReduced() acceptent des pointeurs vers des fonctions membres. Le type de classe de la fonction membre doit correspondre au type stocké dans la séquence :
// ne conserver que les images disposant d’un canal alpha
QList<QImage> images =...;
QFuture<void> alphaImages = QtConcurrent::filter(images,&QImage::hasAlphaChannel);
// récupérer les images en niveaux de gris
QList<QImage> images =...;
QFuture<QImage> imagesEnNiveauxDeGris = QtConcurrent::filtered(images,&QImage::isGrayscale);
// créer un ensemble de tous les caractères imprimables
QList<QChar> caractères =...;
QFuture<QSet<QChar>> ensemble = QtConcurrent::filteredReduced(caractères, qOverload<>(&QChar::isPrint),
qOverload<const QChar&>(&QSet<QChar>::insert));Notez l'utilisation de ` qOverload`. Elle est nécessaire pour lever l'ambiguïté concernant les méthodes qui comportent plusieurs surcharges.
Notez également que lorsque vous utilisez QtConcurrent::filteredReduced(), vous pouvez combiner librement l'utilisation de fonctions normales et de fonctions membres :
// possibilité de combiner des fonctions normales et des fonctions membres avec QtConcurrent::filteredReduced()
// création d'un dictionnaire contenant toutes les chaînes en minuscules
extern bool allLowerCase(const QString&string);
QStringList strings =...;
QFuture<QSet<QString>> lowerCase = QtConcurrent::filteredReduced(strings, allLowerCase,
qOverload<const QString&>(&QSet<QString>::insert));
// créer un collage à partir de toutes les images en niveaux de gris
extern void addToCollage(QImage &collage, const QImage &grayscaleImage);
QList<QImage> images =...;
QFuture<QImage> collage = QtConcurrent::filteredReduced(images,&QImage::isGrayscale, addToCollage);Utilisation des objets-fonctions
QtConcurrent::filter(), QtConcurrent::filtered() et QtConcurrent::filteredReduced() acceptent des objets-fonction pour la fonction de filtrage. Ces objets-fonction peuvent être utilisés pour ajouter un état à un appel de fonction :
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")));Les objets fonction sont également pris en charge pour la fonction reduce :
struct StringTransform
{
void operator()(QString &result, const QString &value);
};
QFuture<QString> fooString =
QtConcurrent::filteredReduced(strings, StartsWith(QLatin1String("Foo")), StringTransform());Utilisation des expressions lambda
Les fonctions QtConcurrent::filter(), QtConcurrent::filtered() et QtConcurrent::filteredReduced() acceptent des expressions lambda pour les fonctions filter et reduce :
// 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;
}
);Lorsque vous utilisez QtConcurrent::filteredReduced() ou QtConcurrent::blockingFilteredReduced(), vous pouvez combiner librement des fonctions normales, des fonctions membres et des expressions lambda.
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
);Vous pouvez également passer un lambda en tant qu’objet de réduction :
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;
}
);Encapsulation de fonctions prenant plusieurs arguments
Si vous souhaitez utiliser une fonction de filtrage prenant plus d’un argument, vous pouvez utiliser une fonction lambda ou une expression « std::bind() » pour la transformer en une fonction prenant un seul argument.
À titre d’exemple, nous utilisons la fonction « QString::contains() » :
bool QString::contains(const QRegularExpression ®exp) const;QString::contains() prend 2 arguments (y compris le pointeur « this ») et ne peut pas être utilisée directement avec QtConcurrent::filtered(), car QtConcurrent::filtered() attend une fonction qui ne prend qu’un seul argument. Pour utiliser QString::contains() avec QtConcurrent::filtered(), nous devons fournir une valeur pour l'argument regexp:
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.