主计数器
演示如何监控并发操作的进度。
下面的示例演示了如何使用QFutureWatcher 类和filteredReduced函数创建一个交互式非阻塞 QtWidgets 应用程序。 Qt Concurrent.通过该示例,用户可以创建一个可调整大小的整数QList 。程序将检查列表中的质数,并显示找到的质数总数。
运行示例
运行示例 Qt Creator,打开Welcome 模式,然后从Examples 中选择示例。更多信息,请参见Qt Creator: 教程:构建并运行。
设置连接
连接 Qt Concurrent库提供了filteredReduced函数,可在两种模式下运行:OrderedReduce and UnorderedReduce 。在OrderedReduce
模式下,还原函数按照原始序列的顺序调用,而在UnorderedReduce
模式下,元素被随机访问。
在用所需元素配置用户界面后,有必要使用 QtSignals & Slots机制将它们连接到并发操作的信号上。在本例中,我们使用QFutureWatcher 类监控并发操作的进度,并提供实现交互式图形用户界面所需的信号。
... 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 类在本示例中起着至关重要的作用,因为它提供了根据并发操作的变化更新用户界面所需的信号。
启动并发操作
连接所有信号和插槽后,当用户按下 QPushButton 时,start()
函数将被调用。
在start()
函数中,我们调用了Qt Concurrent 中的filteredReduced函数,并在QFutureWatcher 成员上设置了 future。为确保这一操作真正并发运行,我们指定了一个单独的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)); ...
让我们来看看过滤器和还原函数。在本例中,这些函数被声明为静态函数,因为它们不依赖于任何成员变量。不过,它们也可以很容易地被指定为 lambdas 或成员函数。
filter 函数标记元素,以便随后使用 reduce 函数进行还原。本例实现的是一个简单的质数过滤器。由于该函数使用常量引用作为参数,因此它允许对其操作的容器进行线程安全操作。
... 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; } ...
© 2025 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.