在 QT UI 程式設計中使用 QtConcurrent 和 QFutureWatcher 執行併發任務
阿新 • • 發佈:2019-02-12
問題
在 QT 的 UI 程式設計中, 如果有一個函式消耗的時間特別長, 並且運行於主執行緒, 那麼介面的響應會很不靈敏. 通常的作法是使用多執行緒編輯.
另外, 如果該函式執行時間很長, 為了通知任務的進度, 一般會使用進度條. 但有時候無法準確的使用進度條, 比如在資料庫操作中, 為了提高讀寫資料庫的效能, 通常會採用事務操作, 多個讀寫資料庫的操作合併成了一個事務, 此時如何設定進度條的進度值?
此時, 可以使用 QtConcurrent 和 QFutureWatcher 來解決這個問題. 對於第一個問題不需多言. 對於第二個問題, 可以在任務開始後以QMessageBox::imformation 對話方塊來告知使用者完成任務需要時間很長, 在任務執行完畢時關閉該對話方塊 (如果使用者沒有關閉的話).
QtConcurrent 和 QFutureWatcher
QtConcurrent 是一個名字空間, 其內包含了眾多的高階 API, 方便使用者編寫多執行緒程式.
QFutureWatcher 可以用於監視執行緒的完成情況, 並獲取執行緒的返回值.
QtConcurrent 執行緒函式與 QFutureWatcher 之間的中間者是 QFuture.
示例程式碼
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFutureWatcher>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
//
void busy_job();
private:
//
int do_busy_job();
//
void busy_job_finished();
private:
Ui::MainWindow *ui;
//
QFutureWatcher<int>* watcher_;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtConcurrent>
#include <QFuture>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//
watcher_ = new QFutureWatcher<int>;
connect(watcher_, &QFutureWatcher<int>::finished,
this, &MainWindow::busy_job_finished);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::busy_job()
{
// 若有需要, 啟動告知對話方塊
auto future = QtConcurrent::run(this, &MainWindow::do_busy_job);
watcher_->setFuture(future);
}
int MainWindow::do_busy_job()
{
return 1;
}
void MainWindow::busy_job_finished()
{
// 若有需要, 關閉通知對話方塊
qDebug() << "busy job finished!";
qDebug() << "the returned value is: "
<< watcher_->result();
}
呼叫
MainWindow w;
w.busy_job();
輸出
busy job finished!
the returned value is: 1