http://blog.csdn.net/zengcccc/article/details/7010891 -- QtConcurrent::run 的一个例子
下面是没有进度条的显示代码
QFutureWatcher<void> futureWatcher; -- 必须是全局变量 -- 局部变量会报错
const int iterations = 20;
struct myTestStruct{
public:
myTestStruct(){}
myTestStruct(QString mserviceName)
{
serviceName=mserviceName;
}
QString resEntity;
QString serviceName;
QString msgfail_out;
};
void spin(myTestStruct &iteration)
{
const int work = 1000 * 1000 * 40;
volatile int v = 0;
for (int j = 0; j < work; ++j)
++v;
iteration.msgfail_out=iteration.serviceName+"xxxx";
qDebug() << "iteration serviceName: " << iteration.serviceName
<< "iteration msgfail_out: " << iteration.msgfail_out
<< "in thread" << QThread::currentThreadId();
}
void MainWindow::on_pushButton_clicked()
{
myVecServieMethodStruct.clear();
QStringList sList;
sList<<"aaa"<<"bbb"<<"ccc"<<"ddd";
foreach(QString var,sList)
{
myTestStruct s1(var);
myVecServieMethodStruct.append(s1);
}
QObject::connect(&futureWatcher, SIGNAL(finished()), this, SLOT(watchOvered()));
futureWatcher.setFuture(QtConcurrent::map(myVecServieMethodStruct, spin));
futureWatcher.waitForFinished();
}
void MainWindow::watchOvered()
{
foreach(myTestStruct var,myVecServieMethodStruct)
{
qDebug()<<"watchOvered:"<<var.serviceName<<var.msgfail_out;
}
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
QFutureWatcher<bool> *watcher;
static int spin(int &iteration);
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_tab2_clicked();
private:
Ui::MainWindow *ui;
MyClass mycls;
int testCatch();
template <typename T>
void showProgressDlg(QFuture<T> future);
};
template <typename T>
void MainWindow::showProgressDlg(QFuture<T> future)
{
QFutureWatcher<T> watcher;
watcher.waitForFinished();
//connect( watcher, SIGNAL( finished() ), &mycls, SLOT( taskCompleted() ) );
QProgressDialog pDlg(this,Qt::FramelessWindowHint);
//QProgressDialog pDlg;
//pDlg.setLabel("xxxxxxxxx");
pDlg.setCancelButton(NULL);
pDlg.setLabelText(QString("Progressing xx using %1 thread(s)...").arg(QThread::idealThreadCount()));
QObject::connect(&watcher, SIGNAL(finished()), &pDlg, SLOT(reset()));
QObject::connect(&watcher, SIGNAL(progressRangeChanged(int,int)), &pDlg, SLOT(setRange(int,int)));
QObject::connect(&watcher, SIGNAL(progressValueChanged(int)), &pDlg, SLOT(setValue(int)));
watcher.setFuture( future );
pDlg.exec();
}
void MainWindow::on_tab2_clicked()
{
MyClass cls1;QString s="pathxx";
mystruct struct1;struct1.s1="s1xx";struct1.i1=111;struct1.s2="s2yyy";
QFuture<QString> future = QtConcurrent::run(&cls1,&MyClass::record,struct1, 20, 30, s);
showProgressDlg<QString>(future);
QString sres = future.result();
qDebug() << "sres" << sres << QThread::currentThread() <<QTime::currentTime()<<s;
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QThread>
#include <QtDebug>
#include <QTime>
#include <QSplashScreen>
#include <QXmlStreamReader>
#include <QPixmap>
#include <QDesktopWidget>
#include "formDlg.h"
#include <QtConcurrent>
using namespace QtConcurrent;
namespace Ui {
class MainWindow;
}
class MyClass: public QObject
{
Q_OBJECT
public:
bool performTask();
private slots:
void taskCompleted();
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
QFutureWatcher<bool> *watcher;
static int spin(int &iteration);
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_tab2_clicked();
private:
Ui::MainWindow *ui;
MyClass mycls;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>
#include <QMessageBox>
#include <QTime>
#include <QProgressDialog>
#include "moc_mainwindow.cpp"
const int iterations = 20;
void spin(int &iteration)
{
const int work = 1000 * 1000 * 40;
volatile int v = 0;
for (int j = 0; j < work; ++j)
++v;
qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
}
void MainWindow::on_tab2_clicked()
{
#if 1
//! 在此段代码中,若bool MyClass::performTask()没有执行完,会重新开一个新的线程,开始一个新的循环来执行 QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race
QFuture<bool> future = QtConcurrent::run(&mycls, &MyClass::performTask );
//QtConcurrent::map(vector, spin)
//QVector<int> vector;
//vector.append(1);
//watcher->setFuture(QtConcurrent::map(vector, MyClass::performTask));
connect( watcher, SIGNAL( finished() ), &mycls, SLOT( taskCompleted() ) );
QProgressDialog pDlg;
pDlg.setCancelButton(NULL);
pDlg.setLabelText(QString("Progressing xx using %1 thread(s)...").arg(QThread::idealThreadCount()));
QObject::connect(watcher, SIGNAL(finished()), &pDlg, SLOT(reset()));
QObject::connect(watcher, SIGNAL(progressRangeChanged(int,int)), &pDlg, SLOT(setRange(int,int)));
QObject::connect(watcher, SIGNAL(progressValueChanged(int)), &pDlg, SLOT(setValue(int)));
watcher->setFuture( future );
pDlg.exec();
qDebug()<<"future.begin(); before"<<QThread::currentThreadId()<<QTime::currentTime();
//future.begin();
watcher->waitForFinished();
qDebug()<<"future.begin(); after"<<QThread::currentThreadId()<<QTime::currentTime();
#endif
#if 0
QVector<int> vector;
for (int i = 0; i < iterations; ++i)
vector.append(i);
// Create a progress dialog.
QProgressDialog dialog;
dialog.setLabelText(QString("Progressing using %1 thread(s)...").arg(QThread::idealThreadCount()));
// Create a QFutureWatcher and connect signals and slots.
QFutureWatcher<void> futureWatcher;
QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
// Start the computation.
futureWatcher.setFuture(QtConcurrent::map(vector, spin));
// Display the dialog and start the event loop.
dialog.exec();
futureWatcher.waitForFinished();
// Query the future to check if was canceled.
qDebug() << "Canceled?" << futureWatcher.future().isCanceled();
#endif
}
//! 新的线程中执行
bool MyClass::performTask()
{
qDebug()<<"bool MyClass::performTask()"<<QThread::currentThreadId()<<QTime::currentTime();
QThread::sleep(1);
for(int i=0;i<INT_MAX;i++){}QThread::sleep(1);
for(int j=0;j<INT_MAX;j++){}QThread::sleep(1);
// for(int k=0;k<INT_MAX;k++)
{}
return true;
qDebug()<<"bool MyClass::performTask() after"<<QThread::currentThreadId()<<QTime::currentTime();
}
//! 主线程中执行
void MyClass::taskCompleted()
{
qDebug()<<"bool MyClass::taskCompleted()"<<QThread::currentThreadId()<<QTime::currentTime();
}
int MainWindow::spin(int &iteration)
{
const int work = 1000 * 1000 * 40;
volatile int v = 0;
for (int j = 0; j < work; ++j)
++v;
return 22;
qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
watcher = new QFutureWatcher<bool>();
}
MainWindow::~MainWindow()
{
delete watcher;
delete ui;
}
下面是若干例子: 此例子函数可以是一个类的静态成员函数
void hello(QString name)
{
qDebug() << "Hello" << name << "from" << QThread::currentThread();
}
void hello(int age)
{
qDebug() << "Hello" << age << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QFuture<void> f1 = run(static_cast<void(*)(QString)>(hello), QString("Alice"));
QFuture<void> f2 = run(static_cast<void(*)(int)>(hello), 42);
f1.waitForFinished();
f2.waitForFinished();
}
QFuture<QString> f1 = run(static_cast<QString(*)(int,bool)>(MyClass::performTask), int(44),bool(false));
int b=99;
QFuture<QString> f1 = run(static_cast<QString(*)(int,bool)>(MyClass::performTask), int(b),bool(false));
QFuture<QString> f1 = run(static_cast<QString(*)(int&,bool)>(MyClass::performTask), int(b),bool(false));
int b=99;
QFuture<QString> f1 = run(static_cast<QString(*)(int&,bool)>(MyClass::performTask), int(b),bool(false));
//QFuture<QString> f1 = run(this, &MyClass::performTask, Operation, 44);
//QFuture<void> f1 = run(static_cast<void(*)(QString)>(hello), QString("Alice"));
//QFuture<void> f2 = run(static_cast<void(*)(int)>(hello), 42);
#if 1
QFutureWatcher<QString> watcher;
watcher.waitForFinished();
//connect( watcher, SIGNAL( finished() ), &mycls, SLOT( taskCompleted() ) );
QProgressDialog pDlg;
pDlg.setCancelButton(NULL);
pDlg.setLabelText(QString("Progressing xx using %1 thread(s)...").arg(QThread::idealThreadCount()));
QObject::connect(&watcher, SIGNAL(finished()), &pDlg, SLOT(reset()));
QObject::connect(&watcher, SIGNAL(progressRangeChanged(int,int)), &pDlg, SLOT(setRange(int,int)));
QObject::connect(&watcher, SIGNAL(progressValueChanged(int)), &pDlg, SLOT(setValue(int)));
watcher.setFuture( f1 );
pDlg.exec();
QString sres = f1.result();
qDebug() << "sres" << sres << QThread::currentThread() <<QTime::currentTime();
#endif
void MyClass::scan()
{
for(int i=0;i<5;i++)
{
QtConcurrent::run(this,&MyClass::scanThread,i);
}
}
void MyClass::scanThread(int i)
{
qDebug() << "scanThread i= " << i << QThread::currentThreadId();
#if 0
int dh;
QString ip;
ip="smb://"+ipList[i]+"/";
dh= smbc_opendir(ip.toAscii()); // debugger points to this location
if(dh<0)
return;
emit
updateTree(i,dh); // on commenting this line, it still crashes
#endif
}
MyClass cls1;
cls1.scan();
QFuture<void> t1 = QtConcurrent::run(thread_process1, (void *)this);
QFuture<void> t2 = QtConcurrent::run(thread_process2, (void *)this);
void record(int index, int time, int frames, QString path);
QString MyClass::record(int index, int time, int frames, QString path)
{
//QFuture<void> future = run(MyClass::recordAsync,index,time,frames, path);
qDebug() << "scanThread i= " << index <<time<< frames<<path<<QThread::currentThreadId();
return "xxaaa";
}
void MainWindow::on_tab2_clicked()
{
MyClass cls1;QString s="pathxx";
//QFuture<void> future = QtConcurrent::run(MyClass,record,index,time,frames, path);
QFuture<QString> future = QtConcurrent::run(&cls1,&MyClass::record,10, 20, 30, s);
QString res = future.result();
qDebug() <<"res= "<<res<<QThread::currentThreadId();
struct mystruct{
QString s1;
int i1;
QString s2;
};
//Q_DECLARE_METATYPE(mystruct)
QString record(mystruct index, int time, int frames, QString path);
QString MyClass::record(mystruct index, int time, int frames, QString path)
{
//QFuture<void> future = run(MyClass::recordAsync,index,time,frames, path);
qDebug() << "scanThread i= " << index.s1+" "+index.s2 <<time<< frames<<path<<QThread::currentThreadId();
return "ret--xxaaa";
}
void MainWindow::on_tab2_clicked()
{
MyClass cls1;QString s="pathxx";
mystruct struct1;struct1.s1="s1xx";struct1.i1=111;struct1.s2="s2yyy";
//QFuture<void> future = QtConcurrent::run(MyClass,record,index,time,frames, path);
QFuture<QString> future = QtConcurrent::run(&cls1,&MyClass::record,struct1, 20, 30, s);
QString res = future.result();
qDebug() <<"res= "<<res<<QThread::currentThreadId();