Prime Counter
演示如何监控并发操作的进度。
以下示例演示了如何使用QFutureWatcher 类以及来自 Qt Concurrent中的QList 类和filteredReduced函数来创建一个交互式且非阻塞的QtWidgets应用程序。通过此示例,用户可以创建一个可调整大小的整数 。该列表将自动填充从1到n的自然数。随后,程序将检查列表中的质数,并显示找到的质数总数。

运行示例
您可以通过以下方式运行该示例:
- Qt Creator
打开Welcome 模式,并从Examples 中选择该示例。有关更多信息,请参阅Qt Creator :教程:构建和运行。
- Qt Extension for Visual Studio Code
在Command Palette 中运行Qt: Open Qt examples 命令,并从列表中选择该示例。有关更多信息,请参阅Qt Extension for Visual Studio Code :教程:构建和运行。
设置连接
该 Qt Concurrent 库提供了filteredReduced函数,该函数支持两种模式:OrderedReduce and UnorderedReduce 。在OrderedReduce 模式下,缩减函数按原始序列的顺序被调用;而在UnorderedReduce 模式下,则随机访问元素。
在 UI 中配置好所需元素后,必须使用 Qt信号与槽机制将它们连接到并发操作的信号上。在本例中,我们使用 `QFutureWatcher ` 类来监控并发操作的进度,并提供实现交互式 GUI 所需的信号。
...
connect(ui->pushButton, &QPushButton::clicked,
this, [this] { start(); });
connect(&watcher, &QFutureWatcher<Element>::finished,
this, [this] { finish(); });
connect(&watcher, &QFutureWatcher<Element>::progressRangeChanged,
ui->progressBar, &QProgressBar::setRange);
connect(&watcher, &QFutureWatcher<Element>::progressValueChanged,
ui->progressBar, &QProgressBar::setValue);
...QFutureWatcher 类在本例中起着至关重要的作用,因为它提供了响应并发操作变化而更新UI所需的信号。
启动并发操作
在连接所有信号与槽后,当用户按下 QPushButton 时,将调用 `start() ` 函数。
在start() 函数中,我们调用Qt Concurrent 中的filteredReduced函数,并将未来对象设置在QFutureWatcher 成员上。为了确保该操作真正并发运行,我们将一个独立的QThreadPool 作为第一个参数传入。这种做法还能避免全局线程池中可能出现的阻塞。 我们将整数类型的QList 作为容器传递,同时传递静态的过滤函数和归约函数,最后指定ReduceOption 标志。
...
void PrimeCounter::start()
{
if (ui->pushButton->isChecked()) {
ui->comboBox->setEnabled(false);
ui->pushButton->setText(tr("Cancel"));
ui->labelResult->setText(tr("Calculating ..."));
ui->labelFilter->setText(tr("Selected Reduce Option: %1").arg(ui->comboBox->currentText()));
fillElementList(ui->horizontalSlider->value() * stepSize);
timer.start();
watcher.setFuture(
QtConcurrent::filteredReduced(
&pool,
elementList,
filterFunction,
reduceFunction,
currentReduceOpt | QtConcurrent::SequentialReduce));
...让我们来分析一下 filter 和 reduce 函数。由于这些函数不依赖于任何成员变量,因此在本例中被声明为静态函数。不过,它们也可以轻松地指定为 lambda 表达式或成员函数。
filter 函数负责标记元素,以便后续由 reduce 函数进行归约。此实现是一个简单的素数过滤器。由于该函数将 const 引用作为参数,因此它可以在所操作的容器上进行线程安全操作。
...
bool PrimeCounter::filterFunction(const Element &element)
{
// Filter for primes
if (element <= 1)
return false;
for (Element i = 2; i*i <= element; ++i) {
if (element % i == 0)
return false;
}
return true;
}
...reduce 函数将操作容器的同类型可修改引用作为其第一个参数。第二个参数是来自 filter 函数的先前过滤后的元素。在此示例中,我们统计素数的个数。
...
void PrimeCounter::reduceFunction(Element &out, const Element &value)
{
// Count the amount of primes.
Q_UNUSED(value);
++out;
}
...© 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.