Qt多线程继承自QObject类方法二

新建一个类,继承自QObject类,在类中设置一个线程函数。通过发出mySignal信号调用处理槽函数。

class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr);

    //线程处理函数
    void myTimeout();

    void setFlag(bool flag = true);

signals:
    void mySignal();

public slots:

private:
    bool isStop;
};

不能直接调用线程函数,否则仍然属于同一线程,通过startThread信号启动子线程。

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();
    void dealSignal();
    void dealClose();

signals:
    void startThread();//指定子线程信号

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MyWidget *ui;
    MyThread * myT;
    QThread * thread;
};

与继承自QThread类方法一样,通过emit mySignal()信号,连接执行槽函数。

MyThread::MyThread(QObject *parent) : QObject(parent)
{
    isStop = false;
}

void MyThread::myTimeout()
{
    while (isStop == false) {
        QThread::sleep(1);
        emit mySignal();
        qDebug()<<"子线程号:"<<QThread::currentThread();
    }
}

void MyThread::setFlag(bool flag)
{
    isStop = flag;
}

在Widget.cpp文件中实现主线程。
步骤

  1. 创建一个线程对象,不能指定父对象
    myT = new MyThread;

  2. 创建一个QThread子线程对象
    QThread * thread = new QThread(this);

  3. 把自定义线程对象加入到子线程
    myT -> movetoThread(thread);

  4. 启动子线程,只开启了线程,并没有启动线程处理函数
    thread.start();

  5. 通过Signal - slot方式启动线程函数

connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout);

代码如下:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    //动态分配空间,不能指定父对象
    myT = new MyThread;

    //创建子线程
    thread = new QThread(this);

    //把自定义线程加入到子线程中
    myT->moveToThread(thread);
    
    connect(myT,&MyThread::mySignal,this,&MyWidget::dealSignal);

    qDebug()<<"主线程号:"<<QThread::currentThread();

    connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout);

    connect(this,&MyWidget::destroyed,this,&MyWidget::dealClose);
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::dealClose()
{
    on_pushButton_2_clicked();
    delete myT;
}

void MyWidget::dealSignal()
{
    static int i = 0;
    i++;
    ui->lcdNumber->display(i);
}

void MyWidget::on_pushButton_clicked()
{
    //启动线程,但是没有启动线程处理函数
    thread->start();
    myT->setFlag(false);
    //不能直接调用线程处理函数
    //直接调用,导致线程处理函数和主线程是在同一个线程

    //只能通过 signal-slot 方式调用
    emit startThread();
}

void MyWidget::on_pushButton_2_clicked()
{
    myT->setFlag(true);
    thread->quit();
    thread->wait();
}

总结

1、Start按钮 -> 启动线程,线程标志false,
emit startThread()信号 -> connect() ->MyThread::MyTimeout() -> 开启线程函数,执行复杂处理 ,
emit mySignal()信号 -> connect() ->MyWidget::dealSignal,将线程处理结束信号发送到主线程。
2、Stop按钮 -> 关闭线程,设置线程标志位true。
3、点击窗口右上角X,使用connect()信号和槽,释放myT内存,关闭线程。

你可能感兴趣的:(Qt使用类,Qt线程使用)