Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 线程在Qt中的应用_C++_Multithreading_Qt - Fatal编程技术网

C++ 线程在Qt中的应用

C++ 线程在Qt中的应用,c++,multithreading,qt,C++,Multithreading,Qt,我正在学习Qt中的线程管理,如果我犯了一些小错误,请向我道歉。让我们回到话题上来 简短描述: #ifndef WORKER_H #define WORKER_H #include <QObject> #include <QMutex> class Worker : public QObject { Q_OBJECT public: explicit Worker(QObject *parent = nullptr); void stop();

我正在学习Qt中的线程管理,如果我犯了一些小错误,请向我道歉。让我们回到话题上来

简短描述:

#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QMutex>

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

    void stop();
    void setMessage(const QString &message);

signals:
    void finished();

public slots:
    void process();

private:
    volatile bool stopped;
    QString messageStr;
    QMutex mutex;
};

#endif // WORKER_H
#include "worker.h"
#include <QDebug>

Worker::Worker(QObject *parent)
    : QObject(parent)
{
    stopped = false;
}

void Worker::process()
{
    forever
    {
        mutex.lock();
        if(stopped)
        {
            stopped = false;
            mutex.unlock();
            break;
        }
        mutex.unlock();
        qDebug() << messageStr;
    }
    emit finished();
}

void Worker::stop()
{
    mutex.lock();
    stopped = true;
    mutex.unlock();
}

void Worker::setMessage(const QString &message)
{
    messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

class Worker;

class MyDialog : public QDialog
{
    Q_OBJECT
public:
    MyDialog(QWidget *parent = nullptr);

private slots:
    void startStopThreadA();
    void startStopThreadB();
    void showWorkingGUI();

private:
    Worker *workerA;
    Worker *workerB;
    QThread *threadA;
    QThread *threadB;
    QPushButton *threadAButton;
    QPushButton *threadBButton;
    QPushButton *quitButton;

};

#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"

#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>

MyDialog::MyDialog(QWidget *parent)
    : QDialog(parent)
{
    //Here bla bla for gui
    threadAButton = new QPushButton(tr("Start A"));
    threadBButton = new QPushButton(tr("Start B"));
    quitButton = new QPushButton(tr("Quit"));

    connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
    connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));

    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(threadAButton);
    layout->addWidget(threadBButton);
    layout->addWidget(quitButton);

    setLayout(layout);

    //Create worker's instances
    workerA = new Worker;
    workerB = new Worker;

    workerA->setMessage("Thread 1");
    workerB->setMessage("Thread 2");

    //Create threads instances
    threadA = new QThread;
    threadB = new QThread;

    //Move worker to thread
    workerA->moveToThread(threadA);
    workerB->moveToThread(threadB);

    connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
    connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
    connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
    connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));

    connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
    connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
    connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
    connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
    timer->start(1000);

}

void MyDialog::startStopThreadA()
{
    if(threadA->isRunning())
    {
        workerA->stop();
        threadAButton->setText(tr("Start A"));
    }
    else
    {
        threadA->start();
        threadAButton->setText(tr("Stop A"));
    }
}

void MyDialog::startStopThreadB()
{
    if(threadB->isRunning())
    {
        workerB->stop();
        threadBButton->setText(tr("Start B"));
    }
    else
    {
        threadB->start();
        threadBButton->setText(tr("Stop B"));
    }
}

void MyDialog::showWorkingGUI()
{
    qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyDialog dialog;
    dialog.show();
    return a.exec();
}
我编写了一个测试线程如何工作的小应用程序。我有两个按钮的简单GUI界面。它们可以启动和停止不同的线程。线程基于下的工作者类。我正在使用Ubuntu 16.04 LTS x64下的Qt Creator编译代码

主要问题:

#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QMutex>

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

    void stop();
    void setMessage(const QString &message);

signals:
    void finished();

public slots:
    void process();

private:
    volatile bool stopped;
    QString messageStr;
    QMutex mutex;
};

#endif // WORKER_H
#include "worker.h"
#include <QDebug>

Worker::Worker(QObject *parent)
    : QObject(parent)
{
    stopped = false;
}

void Worker::process()
{
    forever
    {
        mutex.lock();
        if(stopped)
        {
            stopped = false;
            mutex.unlock();
            break;
        }
        mutex.unlock();
        qDebug() << messageStr;
    }
    emit finished();
}

void Worker::stop()
{
    mutex.lock();
    stopped = true;
    mutex.unlock();
}

void Worker::setMessage(const QString &message)
{
    messageStr = message;
}
#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

class Worker;

class MyDialog : public QDialog
{
    Q_OBJECT
public:
    MyDialog(QWidget *parent = nullptr);

private slots:
    void startStopThreadA();
    void startStopThreadB();
    void showWorkingGUI();

private:
    Worker *workerA;
    Worker *workerB;
    QThread *threadA;
    QThread *threadB;
    QPushButton *threadAButton;
    QPushButton *threadBButton;
    QPushButton *quitButton;

};

#endif // MYDIALOG_H
#include "mydialog.h"
#include "worker.h"

#include <QCloseEvent>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QDebug>
#include <QTimer>

MyDialog::MyDialog(QWidget *parent)
    : QDialog(parent)
{
    //Here bla bla for gui
    threadAButton = new QPushButton(tr("Start A"));
    threadBButton = new QPushButton(tr("Start B"));
    quitButton = new QPushButton(tr("Quit"));

    connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
    connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));

    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(threadAButton);
    layout->addWidget(threadBButton);
    layout->addWidget(quitButton);

    setLayout(layout);

    //Create worker's instances
    workerA = new Worker;
    workerB = new Worker;

    workerA->setMessage("Thread 1");
    workerB->setMessage("Thread 2");

    //Create threads instances
    threadA = new QThread;
    threadB = new QThread;

    //Move worker to thread
    workerA->moveToThread(threadA);
    workerB->moveToThread(threadB);

    connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
    connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
    connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
    connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));

    connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
    connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
    connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
    connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
    timer->start(1000);

}

void MyDialog::startStopThreadA()
{
    if(threadA->isRunning())
    {
        workerA->stop();
        threadAButton->setText(tr("Start A"));
    }
    else
    {
        threadA->start();
        threadAButton->setText(tr("Stop A"));
    }
}

void MyDialog::startStopThreadB()
{
    if(threadB->isRunning())
    {
        workerB->stop();
        threadBButton->setText(tr("Start B"));
    }
    else
    {
        threadB->start();
        threadBButton->setText(tr("Stop B"));
    }
}

void MyDialog::showWorkingGUI()
{
    qDebug() << "GUI Thread works!";
}
#include <QApplication>
#include "mydialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyDialog dialog;
    dialog.show();
    return a.exec();
}
  • 当我尝试启动线程时,它工作正常。然后我停下来,试着重新开始。在这种情况下,线程不会启动。也许我用正确的方法合上了线
  • 使用线程进行管理的这种方式合适吗?做得好吗?我了解到,在Qt中,将QObject移动到线程比子类线程更好。(但这要看情况而定,我知道)
  • 我的代码:

    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    #include <QMutex>
    
    class Worker : public QObject
    {
        Q_OBJECT
    public:
        explicit Worker(QObject *parent = nullptr);
    
        void stop();
        void setMessage(const QString &message);
    
    signals:
        void finished();
    
    public slots:
        void process();
    
    private:
        volatile bool stopped;
        QString messageStr;
        QMutex mutex;
    };
    
    #endif // WORKER_H
    
    #include "worker.h"
    #include <QDebug>
    
    Worker::Worker(QObject *parent)
        : QObject(parent)
    {
        stopped = false;
    }
    
    void Worker::process()
    {
        forever
        {
            mutex.lock();
            if(stopped)
            {
                stopped = false;
                mutex.unlock();
                break;
            }
            mutex.unlock();
            qDebug() << messageStr;
        }
        emit finished();
    }
    
    void Worker::stop()
    {
        mutex.lock();
        stopped = true;
        mutex.unlock();
    }
    
    void Worker::setMessage(const QString &message)
    {
        messageStr = message;
    }
    
    #ifndef MYDIALOG_H
    #define MYDIALOG_H
    
    #include <QDialog>
    
    class Worker;
    
    class MyDialog : public QDialog
    {
        Q_OBJECT
    public:
        MyDialog(QWidget *parent = nullptr);
    
    private slots:
        void startStopThreadA();
        void startStopThreadB();
        void showWorkingGUI();
    
    private:
        Worker *workerA;
        Worker *workerB;
        QThread *threadA;
        QThread *threadB;
        QPushButton *threadAButton;
        QPushButton *threadBButton;
        QPushButton *quitButton;
    
    };
    
    #endif // MYDIALOG_H
    
    #include "mydialog.h"
    #include "worker.h"
    
    #include <QCloseEvent>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QThread>
    #include <QDebug>
    #include <QTimer>
    
    MyDialog::MyDialog(QWidget *parent)
        : QDialog(parent)
    {
        //Here bla bla for gui
        threadAButton = new QPushButton(tr("Start A"));
        threadBButton = new QPushButton(tr("Start B"));
        quitButton = new QPushButton(tr("Quit"));
    
        connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
        connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
    
        QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(threadAButton);
        layout->addWidget(threadBButton);
        layout->addWidget(quitButton);
    
        setLayout(layout);
    
        //Create worker's instances
        workerA = new Worker;
        workerB = new Worker;
    
        workerA->setMessage("Thread 1");
        workerB->setMessage("Thread 2");
    
        //Create threads instances
        threadA = new QThread;
        threadB = new QThread;
    
        //Move worker to thread
        workerA->moveToThread(threadA);
        workerB->moveToThread(threadB);
    
        connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
        connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
        connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
        connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
    
        connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
        connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
        connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
        connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
    
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
        timer->start(1000);
    
    }
    
    void MyDialog::startStopThreadA()
    {
        if(threadA->isRunning())
        {
            workerA->stop();
            threadAButton->setText(tr("Start A"));
        }
        else
        {
            threadA->start();
            threadAButton->setText(tr("Stop A"));
        }
    }
    
    void MyDialog::startStopThreadB()
    {
        if(threadB->isRunning())
        {
            workerB->stop();
            threadBButton->setText(tr("Start B"));
        }
        else
        {
            threadB->start();
            threadBButton->setText(tr("Stop B"));
        }
    }
    
    void MyDialog::showWorkingGUI()
    {
        qDebug() << "GUI Thread works!";
    }
    
    #include <QApplication>
    #include "mydialog.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MyDialog dialog;
        dialog.show();
        return a.exec();
    }
    
    worker.h:

    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    #include <QMutex>
    
    class Worker : public QObject
    {
        Q_OBJECT
    public:
        explicit Worker(QObject *parent = nullptr);
    
        void stop();
        void setMessage(const QString &message);
    
    signals:
        void finished();
    
    public slots:
        void process();
    
    private:
        volatile bool stopped;
        QString messageStr;
        QMutex mutex;
    };
    
    #endif // WORKER_H
    
    #include "worker.h"
    #include <QDebug>
    
    Worker::Worker(QObject *parent)
        : QObject(parent)
    {
        stopped = false;
    }
    
    void Worker::process()
    {
        forever
        {
            mutex.lock();
            if(stopped)
            {
                stopped = false;
                mutex.unlock();
                break;
            }
            mutex.unlock();
            qDebug() << messageStr;
        }
        emit finished();
    }
    
    void Worker::stop()
    {
        mutex.lock();
        stopped = true;
        mutex.unlock();
    }
    
    void Worker::setMessage(const QString &message)
    {
        messageStr = message;
    }
    
    #ifndef MYDIALOG_H
    #define MYDIALOG_H
    
    #include <QDialog>
    
    class Worker;
    
    class MyDialog : public QDialog
    {
        Q_OBJECT
    public:
        MyDialog(QWidget *parent = nullptr);
    
    private slots:
        void startStopThreadA();
        void startStopThreadB();
        void showWorkingGUI();
    
    private:
        Worker *workerA;
        Worker *workerB;
        QThread *threadA;
        QThread *threadB;
        QPushButton *threadAButton;
        QPushButton *threadBButton;
        QPushButton *quitButton;
    
    };
    
    #endif // MYDIALOG_H
    
    #include "mydialog.h"
    #include "worker.h"
    
    #include <QCloseEvent>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QThread>
    #include <QDebug>
    #include <QTimer>
    
    MyDialog::MyDialog(QWidget *parent)
        : QDialog(parent)
    {
        //Here bla bla for gui
        threadAButton = new QPushButton(tr("Start A"));
        threadBButton = new QPushButton(tr("Start B"));
        quitButton = new QPushButton(tr("Quit"));
    
        connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
        connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
    
        QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(threadAButton);
        layout->addWidget(threadBButton);
        layout->addWidget(quitButton);
    
        setLayout(layout);
    
        //Create worker's instances
        workerA = new Worker;
        workerB = new Worker;
    
        workerA->setMessage("Thread 1");
        workerB->setMessage("Thread 2");
    
        //Create threads instances
        threadA = new QThread;
        threadB = new QThread;
    
        //Move worker to thread
        workerA->moveToThread(threadA);
        workerB->moveToThread(threadB);
    
        connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
        connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
        connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
        connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
    
        connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
        connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
        connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
        connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
    
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
        timer->start(1000);
    
    }
    
    void MyDialog::startStopThreadA()
    {
        if(threadA->isRunning())
        {
            workerA->stop();
            threadAButton->setText(tr("Start A"));
        }
        else
        {
            threadA->start();
            threadAButton->setText(tr("Stop A"));
        }
    }
    
    void MyDialog::startStopThreadB()
    {
        if(threadB->isRunning())
        {
            workerB->stop();
            threadBButton->setText(tr("Start B"));
        }
        else
        {
            threadB->start();
            threadBButton->setText(tr("Stop B"));
        }
    }
    
    void MyDialog::showWorkingGUI()
    {
        qDebug() << "GUI Thread works!";
    }
    
    #include <QApplication>
    #include "mydialog.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MyDialog dialog;
        dialog.show();
        return a.exec();
    }
    
    \ifndef WORKER\u H
    #定义WORKER_H
    #包括
    #包括
    班级工作人员:公共QObject
    {
    Q_对象
    公众:
    显式工作者(QObject*parent=nullptr);
    无效停止();
    无效设置消息(常量字符串和消息);
    信号:
    无效完成();
    公众时段:
    无效过程();
    私人:
    挥发性bool停止;
    QString消息str;
    QMutex互斥;
    };
    #endif//WORKER\u H
    
    worker.cpp:

    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    #include <QMutex>
    
    class Worker : public QObject
    {
        Q_OBJECT
    public:
        explicit Worker(QObject *parent = nullptr);
    
        void stop();
        void setMessage(const QString &message);
    
    signals:
        void finished();
    
    public slots:
        void process();
    
    private:
        volatile bool stopped;
        QString messageStr;
        QMutex mutex;
    };
    
    #endif // WORKER_H
    
    #include "worker.h"
    #include <QDebug>
    
    Worker::Worker(QObject *parent)
        : QObject(parent)
    {
        stopped = false;
    }
    
    void Worker::process()
    {
        forever
        {
            mutex.lock();
            if(stopped)
            {
                stopped = false;
                mutex.unlock();
                break;
            }
            mutex.unlock();
            qDebug() << messageStr;
        }
        emit finished();
    }
    
    void Worker::stop()
    {
        mutex.lock();
        stopped = true;
        mutex.unlock();
    }
    
    void Worker::setMessage(const QString &message)
    {
        messageStr = message;
    }
    
    #ifndef MYDIALOG_H
    #define MYDIALOG_H
    
    #include <QDialog>
    
    class Worker;
    
    class MyDialog : public QDialog
    {
        Q_OBJECT
    public:
        MyDialog(QWidget *parent = nullptr);
    
    private slots:
        void startStopThreadA();
        void startStopThreadB();
        void showWorkingGUI();
    
    private:
        Worker *workerA;
        Worker *workerB;
        QThread *threadA;
        QThread *threadB;
        QPushButton *threadAButton;
        QPushButton *threadBButton;
        QPushButton *quitButton;
    
    };
    
    #endif // MYDIALOG_H
    
    #include "mydialog.h"
    #include "worker.h"
    
    #include <QCloseEvent>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QThread>
    #include <QDebug>
    #include <QTimer>
    
    MyDialog::MyDialog(QWidget *parent)
        : QDialog(parent)
    {
        //Here bla bla for gui
        threadAButton = new QPushButton(tr("Start A"));
        threadBButton = new QPushButton(tr("Start B"));
        quitButton = new QPushButton(tr("Quit"));
    
        connect(threadAButton, SIGNAL(clicked()), this, SLOT(startStopThreadA()));
        connect(threadBButton, SIGNAL(clicked()), this, SLOT(startStopThreadB()));
    
        QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(threadAButton);
        layout->addWidget(threadBButton);
        layout->addWidget(quitButton);
    
        setLayout(layout);
    
        //Create worker's instances
        workerA = new Worker;
        workerB = new Worker;
    
        workerA->setMessage("Thread 1");
        workerB->setMessage("Thread 2");
    
        //Create threads instances
        threadA = new QThread;
        threadB = new QThread;
    
        //Move worker to thread
        workerA->moveToThread(threadA);
        workerB->moveToThread(threadB);
    
        connect(threadA, SIGNAL(started()), workerA, SLOT(process()));
        connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
        connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
        connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
    
        connect(threadB, SIGNAL(started()), workerB, SLOT(process()));
        connect(workerB, SIGNAL(finished()), threadB, SLOT(quit()));
        connect(workerB, SIGNAL(finished()), workerB, SLOT(deleteLater()));
        connect(threadB, SIGNAL(finished()), threadB, SLOT(deleteLater()));
    
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(showWorkingGUI()));
        timer->start(1000);
    
    }
    
    void MyDialog::startStopThreadA()
    {
        if(threadA->isRunning())
        {
            workerA->stop();
            threadAButton->setText(tr("Start A"));
        }
        else
        {
            threadA->start();
            threadAButton->setText(tr("Stop A"));
        }
    }
    
    void MyDialog::startStopThreadB()
    {
        if(threadB->isRunning())
        {
            workerB->stop();
            threadBButton->setText(tr("Start B"));
        }
        else
        {
            threadB->start();
            threadBButton->setText(tr("Stop B"));
        }
    }
    
    void MyDialog::showWorkingGUI()
    {
        qDebug() << "GUI Thread works!";
    }
    
    #include <QApplication>
    #include "mydialog.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MyDialog dialog;
        dialog.show();
        return a.exec();
    }
    
    #包括“worker.h”
    #包括
    工作者::工作者(QObject*父)
    :QObject(父对象)
    {
    停止=错误;
    }
    void Worker::process()
    {
    永远
    {
    mutex.lock();
    如果(停止)
    {
    停止=错误;
    mutex.unlock();
    打破
    }
    mutex.unlock();
    qDebug()addWidget(threadAButton);
    布局->添加小部件(线程按钮);
    布局->添加小部件(退出按钮);
    设置布局(布局);
    //创建工人的实例
    workerA=新员工;
    workerB=新员工;
    workerA->setMessage(“线程1”);
    workerB->setMessage(“线程2”);
    //创建线程实例
    threadA=新的QThread;
    threadB=新的QThread;
    //将工作线程移动到线程
    workerA->moveToThread(threadA);
    workerB->moveToThread(threadB);
    连接(线程A、信号(已启动())、工作区、插槽(进程());
    连接(工作区、信号(完成())、线程A、插槽(退出());
    连接(workerA,信号(finished()),workerA,插槽(deleteLater());
    连接(threadA、信号(finished())、threadA、插槽(deleteLater());
    连接(螺纹B、信号(已启动())、工件B、插槽(进程());
    连接(workerB、信号(finished())、螺纹b、插槽(quit());
    连接(workerB,信号(finished()),workerB,插槽(deleteLater());
    连接(threadB,信号(finished()),threadB,插槽(deleteLater());
    QTimer*定时器=新的QTimer(此);
    连接(计时器、信号(超时())、此、插槽(showWorkingGUI());
    定时器->启动(1000);
    }
    void MyDialog::startStopThreadA()
    {
    如果(threadA->isRunning())
    {
    workerA->stop();
    threadAButton->setText(tr(“开始A”);
    }
    其他的
    {
    threadA->start();
    threadAButton->setText(tr(“停止A”);
    }
    }
    void MyDialog::startStopThreadB()
    {
    如果(threadB->isRunning())
    {
    workerB->stop();
    线程按钮->设置文本(tr(“开始B”);
    }
    其他的
    {
    threadB->start();
    线程按钮->设置文本(tr(“停止B”);
    }
    }
    void MyDialog::showWorkingGUI()
    {
    
    qDebug()在button方法中创建新对象,而不是
    MyDialog
    ctor解决了我的问题。例如:

    void MainWindow::startStopThreadA()
    {
        //First method - start/stop thread
        if(threadA && threadA->isRunning())
        {
            workerA->stop();
            threadA = nullptr;
            ui->threadAButton->setText("Start A");
        }
        else
        {
            threadA = new QThread;
            workerA = new WorkerObject;
            workerA->setMessage("Thread A running");
            workerA->moveToThread(threadA);
    
            connect(threadA, SIGNAL(started()), workerA, SLOT(process()), Qt::QueuedConnection);
            connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
            connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
            connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
    
            threadA->start();
            ui->threadAButton->setText("Stop A");
        }
    }
    

    当我尝试启动线程时,它工作正常。然后我停止它并尝试重新启动。在这种情况下,线程不会启动。可能我正在以正确的方式关闭线程?我想你只能启动一个线程1次。你可能想强制此
    连接(threadA,SIGNAL(start()),workerA,SLOT(process());
    使用
    Qt::QueuedConnection
    “volatile bool stopped;”-注意:
    volatile
    并不意味着线程安全。您可能希望
    atomic
    在那里。线程停止后会被破坏。因此,在释放
    threadA
    后,如果(threadA->isRunning())调用
    MyDialog::startStopThreadA()
    如果需要,可以使用@JesperJuhl提供的有关原子线程的建议创建一个新线程,以确定它是否已停止。