rem*_*ght 1 c++ qt multithreading qt-signals qt5
我正在尝试更新QProgressDialog(由QMainWindow类拥有)沿着执行一些耗时操作的QThread.线程在操作期间发出一些信号,以通知调用应用程序有关进展.我正在寻找将线程发出的进度信号连接到QProgressDialog的setValue槽以更新进度条.
它不起作用!不显示进度对话框.如果我在QMainWindow中添加一个插槽并将其连接到工作进度信号以显示线程通过qDebug输出给出的值,我看到信号似乎在线程操作期间被堆叠并且仅在结束时被取消堆叠.线.
我尝试过DirectConnection connect选项但没有成功.
这是我的代码:qapp.cpp
#include "qapp.h"
#include <threaded.h>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
#include <QProgressDialog>
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()
{
}
Run Code Online (Sandbox Code Playgroud)
threaded.cpp:
#include "threaded.h"
#include <QDebug>
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);
}
}
Run Code Online (Sandbox Code Playgroud)
qapp.h
#ifndef QAPP_H
#define QAPP_H
#include <QMainWindow>
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
Run Code Online (Sandbox Code Playgroud)
threaded.h
#ifndef THREADED_H
#define THREADED_H
#include <QObject>
#include <QThread>
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
Run Code Online (Sandbox Code Playgroud)
该代码的输出k <100是:
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
Run Code Online (Sandbox Code Playgroud)
如果我重新加入worker.wait(); 通过
int k=0;
while(worker.isRunning())
{
qDebug() << "main " << k;
k++;
}
Run Code Online (Sandbox Code Playgroud)
我得到线程的输出和调用方法的输出交错.它确认我的线程独立于调用方法.
关于我做错了什么的任何想法?
绝对错误的使用QThread).看看实现QThread的正确方法是什么......(请举例......).你需要学习线程的基础知识.
您的错误:
1.在本地范围内创建一个静态线程对象;
2.等待主线程完成;
3.不要启动线程;
4. doHeavyCaclulations()主线程中的直接调用方法;
5.发出没有工作事件循环信号的信号......
为了您的目的,您需要:
不要继承QThread.只需创建Work具有必要功能的简单类:
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();
//...
}
Run Code Online (Sandbox Code Playgroud)