如何在不同步的情况下使用QThreads

时间:2018-08-08 08:08:30

标签: qt qthread

我有A,B和C三班;

这是A类: A.h

#ifndef A_H
#define A_H

#include <QObject>

class A : public QObject {

    Q_OBJECT

public:

    A();

    void doWork();

signals:

    void ready(QString str, QVector<double> v);
};

#endif // A_H

A.cpp

#include "A.h"

#include <QVector>

A::A() {

}

void A::doWork() {

    QVector<double> x;
    for(int i = 0 ; i < 10; i++) {
        x.push_back(i);
    }

    emit ready("A ready", x);
}

B和C完全相同。 B类中只有doWork中的循环直到10000年,C类中直到100000000(8个零)为止。

仅出于测试使用QThreads的目的,我创建了3个QLabel:

QLabel* lbl_a;
QLabel* lbl_b;
QLabel* lbl_c;

这是我的MainWindow代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include "A.h"
#include "B.h"
#include "C.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);

    ~MainWindow();

public slots:

    void handlerA(QString str, QVector<double> v);
    void handlerB(QString str, QVector<double> v);
    void handlerC(QString str, QVector<double> v);


private slots:
    void on_btn_start_clicked();

private:
    Ui::MainWindow *ui;

    A* a;
    B* b;
    C* c;
    QThread thread_a;
    QThread thread_b;
    QThread thread_c;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {

    ui->setupUi(this);

    a = new A();
    b = new B();
    c = new C();

    a->moveToThread(&thread_a);
    b->moveToThread(&thread_b);
    c->moveToThread(&thread_c);

    connect(a, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerA(QString, QVector<double>)));
    connect(b, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerB(QString, QVector<double>)));
    connect(c, SIGNAL(ready(QString, QVector<double>)), this, SLOT(handlerC(QString, QVector<double>)));

    thread_a.start();
    thread_b.start();
    thread_c.start();
}

MainWindow::~MainWindow() {


    thread_a.wait();
    thread_b.wait();
    thread_c.wait();
    delete ui;
}

void MainWindow::handlerA(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_a->setText(str);
}

void MainWindow::handlerB(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_b->setText(str);
}

void MainWindow::handlerC(QString str, QVector<double> v) {

    QVector<double> x = v;
    ui->lbl_c->setText(str);
}

void MainWindow::on_btn_start_clicked() {

    a->doWork();
    b->doWrok();
    c->doWork();
}

我希望lbl_a首先出现,然后lbl_b然后lbl_c 但是无论我如何更改for循环,它们总是一起出现。

出什么问题了?

1 个答案:

答案 0 :(得分:0)

您没有在每个线程中执行main循环。您正在同一线程doWork线程中执行它们。

这是因为您正在像正常功能一样从插槽on_btn_start_clicked直接调用函数doWork

您应该完全删除对QThread::started()的呼叫。 而是将信号doWork连接到您的doWork函数。这样,一旦线程启动,它将从新线程发出此信号,并从该线程执行您的connect(&thread_a, &QThread::started, a, &A::doWork); 函数。

a

当然,bcdoWork必须是QObject,而功能_id必须是插槽。


注意:从Qt 5.10和C ++ 17开始,您还可以使用静态函数QThread::create,该函数创建一个线程,并在启动时执行传递的函数。