qt qthead里如何响应信号_Qt 5:在QThread工作期间通过信号更新QProgressBar

I'm trying to update a QProgressDialog (owned by a QMainWindow class) along the execution of a QThread who process some time consuming operations. The thread emit some signals during operation in order to inform the calling app about progression. I'm looking to connect the progress signal emitted by the thread to the setValue slot of the QProgressDialog in order to update the progress bar.

It doesn't work ! The progress dialog is not displayed. If I add a slot in my QMainWindow and connect it to the worker progress signal in order to display the value given by the thread throught qDebug output, I see that signals seems to be stacked during the threaded operation and unstacked only at the end of the thread.

I have tryed the DirectConnection connect's option without any success.

Here is my code :

qapp.cpp

#include "qapp.h"

#include

#include

#include

#include

#include

QApp::QApp(QWidget *parent) :

QMainWindow(parent)

{

QVBoxLayout *mainLayout = new QVBoxLayout(this);

QWidget *window = new QWidget(this);

window->setLayout(mainLayout);

setCentralWidget(window);

QPushButton *button = new QPushButton("Run");

mainLayout->addWidget(button);

connect(button, SIGNAL(clicked(bool)), this, SLOT(doSomeWork()));

}

void QApp::doSomeWork()

{

qDebug() << "do some work";

Threaded worker;

worker.doHeavyCaclulations();

QProgressDialog progressDialog("Copying files...", "Abort Copy", 0, 10000, this);

progressDialog.setWindowModality(Qt::WindowModal);

progressDialog.setMinimumDuration(0);

progressDialog.setValue(0);

connect(&worker, SIGNAL(progress(int)), &progressDialog, SLOT(setValue(int)));

connect(&worker, SIGNAL(progress(int)), this, SLOT(displayProgress(int)));

worker.wait();

qDebug() << "end of thread";

}

void QApp::displayProgress(int value)

{

qDebug() << "data received" << value;

}

QApp::~QApp()

{

}

threaded.cpp :

#include "threaded.h"

#include

Threaded::Threaded(QObject *parent) : QThread(parent)

{

}

void Threaded::doHeavyCaclulations()

{

if (!isRunning())

{

qDebug() << "start thread" ;

start();

}

}

void Threaded::run()

{

qDebug() << "running big loop";

for(double k = 0 ; k < 10000 ; k++)

{

qDebug() << k;

emit progress(k);

}

}

qapp.h

#ifndef QAPP_H

#define QAPP_H

#include

class QApp : public QMainWindow

{

Q_OBJECT

public:

explicit QApp(QWidget *parent = 0);

~QApp();

private:

private slots:

void doSomeWork();

void displayProgress(int value);

};

#endif // QAPP_H

threaded.h

#ifndef THREADED_H

#define THREADED_H

#include

#include

class Threaded : public QThread

{

Q_OBJECT

public:

explicit Threaded(QObject *parent = 0);

void doHeavyCaclulations();

void run();

private:

signals:

void progress(int value);

public slots:

};

#endif // THREADED_H

The output of this code with k < 100 is :

do some work

start thread

running big loop

0

1

2

3

[...]

97

98

99

end of big loop

end of thread

data received 17

data received 18

data received 19

[...]

data received 99

If I remplace

worker.wait();

by

int k=0;

while(worker.isRunning())

{

qDebug() << "main " << k;

k++;

}

I get outputs of the thread and output of the calling method interleaved. It confirm that my thread is independant of the calling method.

Any idea about what I'm doing wrong ?

解决方案

Absolutely wrong using of QThread). See what is the correct way to implement a QThread... (example please...). You need to learn thread's basics.

Your mistakes:

1. Create a static thread object in a local scope;

2. Wait for its finish in the main thread;

3. Don't start the thread;

4. Direct call method doHeavyCaclulations() in the main thread;

5. emit signal without working event loop for its deliver...

For your purpose you need:

Don't inherit QThread. Just create simple Work class with the necessary function:

class Work: public QObject

{

Q_OBJECT

public:

Work(){};

virtual ~Work(){};

public slots:

void doHeavyCaclulations() { /* do what you need and emit progress signal */ };

signals:

void progress(int);

}

// Then:

void QApp::doSomeWork()

{

//...

QThread* thread = new QThread(parent);

Work* worker = new Work; // Do not set a parent. The object cannot be moved if it has a parent.

worker->moveToThread(thread);

connect(thread, SIGNAL(finished()), worker, SLOT(deleteLater()));

connect(thread, SIGNAL(started()), worker, SLOT(doHeavyCaclulations()));

connect(worker, SIGNAL(progress(int)), &progressDialog, SLOT(setValue(int)));

thread->start();

//...

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值