QFutureWatcher QFuture

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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值