Qt 多线程实现6组ABC的有序输出到标签中,使用重写run和moveToThread实现多线程,使用mutex和condition_variant实现同步来控制顺序

本文介绍了在Qt中使用两种方法实现三个线程按照A、B、C顺序输出并显示在UI标签中的过程,涉及重写run函数和moveToThread配合信号槽进行线程间通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

        有3条线程,可以分别输出A、B、C,有序的控制输出顺序为ABCABCABCABCABCABC共6组,放到UI的标签中显示,每条线程只能启动一次;

        

分析:

        Qt里面,创建多线程的方式,可以是重写run函数,也可以使用moveToThread的方式,实现顺序控制之后,还得想办法从子线程里面,将结果放到主线程的标签中显示,就得考虑使用信号槽来通信了,因为Qt里面是不能使用子线程来直接创建UI的。

        好了,分析完成,上代码:

核心代码:

方式1:重写run函数的方式

        头文件:

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>



class MyThread : public QThread
{
    Q_OBJECT

public:
    MyThread(int val,QString str);
signals:
    void strSignal(QString);

protected:
    void run();
private:
    int m_val;
    QString m_str;
};

#endif // MYTHREAD_H

源文件:

#include "mythread.h"
#include <mutex>
#include <condition_variable>
#include <QDebug>

using namespace std;

mutex g_mutex;
condition_variable g_conv;
int g_cnt = 0;

MyThread::MyThread(int val,QString str)
{
    m_val = val;
    m_str = str;
}

void MyThread::run()
{
    for(int i=0;i<6;++i){
        unique_lock<mutex> ul(g_mutex);
        g_conv.wait(ul,[=]{return g_cnt % 3 == m_val;});
        qDebug()<<m_str;
        emit strSignal(m_str);
        ++g_cnt;
        g_conv.notify_all();
    }
}

使用的操作:

主界面头文件:

#ifndef TESTMAINWINDOW_H
#define TESTMAINWINDOW_H

#include <QMainWindow>
#include "mythread.h"

namespace Ui {
class TestMainWindow;
}

class TestMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit TestMainWindow(QWidget *parent = 0);
    ~TestMainWindow();
private slots:
    void showStr(QString str);

    void on_pushButton_clicked();

private:
    Ui::TestMainWindow *ui;
    MyThread *m_a;
    MyThread *m_b;
    MyThread *m_c;
};

#endif // TESTMAINWINDOW_H

主界面源文件:

#include "testmainwindow.h"
#include "ui_testmainwindow.h"

TestMainWindow::TestMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::TestMainWindow)
{
    ui->setupUi(this);
    m_a = new MyThread(0,"A");
    m_b = new MyThread(1,"B");
    m_c = new MyThread(2,"C");
    connect(m_a,SIGNAL(strSignal(QString)),this,SLOT(showStr(QString)));
    connect(m_b,SIGNAL(strSignal(QString)),this,SLOT(showStr(QString)));
    connect(m_c,SIGNAL(strSignal(QString)),this,SLOT(showStr(QString)));

}

TestMainWindow::~TestMainWindow()
{
    delete ui;
    m_a->deleteLater();
    m_b->deleteLater();
    m_c->deleteLater();
}

void TestMainWindow::showStr(QString str)
{
    QString text = ui->label->text();
    ui->label->setText(text+str);
}

void TestMainWindow::on_pushButton_clicked()
{
    m_a->start();
    m_b->start();
    m_c->start();
}

运行效果展示:


第二种方式:moveToThread

头文件:

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <mutex>
#include <condition_variable>
using namespace std;

class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread(int val,QString str,QObject *parent = nullptr);

signals:
    void abcSignal(QString);

public slots:
    void showABC();
private:
    int m_val;
    QString m_str;
    static int m_cnt;
    static mutex m_mutex;
    static condition_variable m_conv;

};

#endif // MYTHREAD_H

源文件:

  

#include "mythread.h"
#include <QDebug>
#include <QThread>

int MyThread::m_cnt = 0;
mutex MyThread::m_mutex;
condition_variable MyThread::m_conv;

MyThread::MyThread(int val,QString str,QObject *parent) : QObject(parent)
{
    m_val = val;
    m_str = str;
}

void MyThread::showABC()
{
    qDebug()<<QThread::currentThread()<<m_val<<m_str;
    for(int i=0;i<6;++i){
        unique_lock<mutex> ul(m_mutex);
        m_conv.wait(ul,[=]{return m_cnt % 3 == m_val;});
        emit abcSignal(m_str);
        m_cnt++;
        m_conv.notify_all();
    }
}

使用的操作:

头文件:

#ifndef MOVETTMAINWINDOW_H
#define MOVETTMAINWINDOW_H

#include <QMainWindow>
#include "mythread.h"
#include <QThread>

namespace Ui {
class MoveTTMainWindow;
}

class MoveTTMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MoveTTMainWindow(QWidget *parent = 0);
    ~MoveTTMainWindow();

private slots:
    void on_pushButton_clicked();
    void showABCToLabel(QString str);

private:
    Ui::MoveTTMainWindow *ui;
    MyThread *m_a;
    QThread *m_aThread;

    MyThread *m_b;
    QThread *m_bThread;

    MyThread *m_c;
    QThread *m_cThread;

};

#endif // MOVETTMAINWINDOW_H

源文件:

#include "movettmainwindow.h"
#include "ui_movettmainwindow.h"

MoveTTMainWindow::MoveTTMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MoveTTMainWindow)
{
    ui->setupUi(this);
    m_a = new MyThread(0,"A");
    m_aThread = new QThread;

    m_b = new MyThread(1,"B");
    m_bThread = new QThread;

    m_c = new MyThread(2,"C");
    m_cThread = new QThread;

    m_a->moveToThread(m_aThread);
    m_b->moveToThread(m_bThread);
    m_c->moveToThread(m_cThread);

    connect(m_aThread,SIGNAL(started()),m_a,SLOT(showABC()));
    connect(m_bThread,SIGNAL(started()),m_b,SLOT(showABC()));
    connect(m_cThread,SIGNAL(started()),m_c,SLOT(showABC()));

    connect(m_a,SIGNAL(abcSignal(QString)),this,SLOT(showABCToLabel(QString)));
    connect(m_b,SIGNAL(abcSignal(QString)),this,SLOT(showABCToLabel(QString)));
    connect(m_c,SIGNAL(abcSignal(QString)),this,SLOT(showABCToLabel(QString)));


}

MoveTTMainWindow::~MoveTTMainWindow()
{
    delete ui;
    delete m_a;
    delete m_b;
    delete m_c;
    m_aThread->deleteLater();
    m_bThread->deleteLater();
    m_cThread->deleteLater();
}

void MoveTTMainWindow::on_pushButton_clicked()
{
    m_aThread->start();
    m_bThread->start();
    m_cThread->start();
}

void MoveTTMainWindow::showABCToLabel(QString str)
{
    ui->label->setText(ui->label->text()+str);
}

运行效果展示:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五木大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值