目录
4.4 获取执行结果QFutureWatcher (运行+结果)
1、Header: #include <QtConcrrent>
2、qmake: QT += concurrent
3、 QtConcrrent::run()
QFuture<T> QtConcurrent::run(Function function, ...)
等价于 QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
在单独的线程中运行函数,该线程取自全局QTheadPool。函数不会立即执行,只会在线程可用时运行。
T与函数的返回值类型相同。返回值非空时可以通过QFuture::result()函数访问。
注意:QtConcurrent::run()返回的QFuture不支持取消、暂停和进度报告。返回的QFuture只能用于查询运行/完成状态和函数的返回值。(但其可以结合QFutureWatcher使用,可以参见示例~)
3.1 在单独线程中运行函数
extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);
这将从默认的线程池QThreadPool中获得的单独线程中运行function。也可以使用QFuture和QFutureWatcher类来监视函数状态。
如果要为其指定线程池,可以传递QThreadPool指针作为第一个参数。
extern void aFunction();
QThreadPool pool;
QFuture<void> future = QtConcurrent::run(&pool, aFunction);
3.2 向函数传递参数
向函数传递参数是通过讲参数添加到QtConcrrent::run()中调用完成的,紧跟在函数名之后:
extern void aFunctionWithArguments(int arg1, double arg2, const QString &string);
int integer = ...;
double floatingPoint = ...;
QString string = ...;
QFuture<void> future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);
在QtConcrrent::run()被调用时,那个参数都有一个副本,当线程开始执行函数时,这些值被传递给线程。在调用QtConcrent::run()之后对参数所做的修改无效。
3.3 函数的返回值
函数的返回值均可以通过QFuture获得:
extern QString functionReturningAString();
QFuture<QString> future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();
也可以通过如下方式获得:
extern QString someFunction(const QByteArray &input);
QByteArray bytearray = ...;
QFuture<QString> future = QtConcurrent::run(someFunction, bytearray);
...
QString result = future.result();
注意: future.result()函数会阻塞并等待结果可用。但函数执行完并且结果可用时,使用QFutureWAtcher获取通知。
3.4 附加属性
使用成员函数
QtConcrrent::run()也接受指向成员函数的指针。第一个参数必须是const引用或指向类实例的指针。当调用const成员函数时,传递const引用很有用;通过指针传递对用于修改非const成员函数很有用。
例如,在单独线程中调用QByteArray::split()(一个const成员函数)是这样的:
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread QByteArray bytearray = "hello world"; QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ','); ... QList<QByteArray> result = future.result();
调用非const成员是这样的:
// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread QImage image = ...; QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba); ... future.waitForFinished(); // At this point, the pixels in 'image' have been inverted
使用Lamada表达式
QFuture<void> future = QtConcurrent::run([=]() {
// Code in this block will run in another thread
});
...
4、代码示例
4.1 线程函数为全局函数
//无参
extern void threadFunc(){
qDebug() << "threadFunc";
//do process...
};
QFuture<void> future = QtConcurrent::run(threadFunc);
//带参
extern void threadFunc(QString arg){
qDebug() << "threadFunc :" << arg;
//do process
};
QFuture<void> future = QtConcurrent::run(threadFunc, QString("arg1"));
4.2 线程函数为类成员函数
1、static成员
//无参
static void threadFunc();
void MainWindow::threadFunc()
{
qDebug() << "threadFunc";
//do process...
}
QFuture<void> future = QtConcurrent::run(threadFunc);
//带参
QFuture<void> future = QtConcurrent::run(threadFunc, QString("arg1"));
static void threadFunc(static);
void MainWindow::threadFunc(QString arg)
{
qDebug() << "threadFunc: " << arg;
}
2、非static成员
//无参
QFuture<void> future = QtConcurrent::run(this, &MainWindow::threadFunc);
void threadFunc();
void MainWindow::threadFunc()
{
qDebug() << "threadFunc";
//do process...
}
//带参
QFuture<void> future = QtConcurrent::run(this, &MainWindow::threadFunc,
static void threadFunc(QString);
void MainWindow::threadFunc(QString arg)
{
qDebug() << "threadFunc: " << arg;
}
4.3 线程函数直接使用Lamada表达式
QFuture<void> future = QtConcurrent::run([=](){
qDebug() << "thread func";
//do process...
});
//可访问局部变量
QString str = "arg test";
QFuture<void> future = QtConcurrent::run([=](){
qDebug() << "str " << str;
});
4.4 获取执行结果QFutureWatcher (运行+结果)
QByteArray bytearray = "hello ,world";
QFuture<QString > future = QtConcurrent::run(this, &MainWindow::threadFunc, bytearray);
//QFutureWatcher<QString> *m_watcher = new QFutureWatcher<QString>(this);
m_watcher = new QFutureWatcher<QString>(this);
m_watcher->setFuture(future);
connect(m_watcher, &QFutureWatcher<QString>::finished, [=](){
qDebug() << "finished";
});
QString MainWindow::threadFunc(QByteArray &arg){
qDebug() << "threadFunc:" << arg;
//do process...
return QString("");
};