Qt提供了许多用于处理线程的类和函数,我们可以在从其中选择一种合适的来实现。总结下来一共有4种:
下面就通过示例来展示每种方式的使用。示例是参考Qt帮助文档,在Qt5.9.8 MSVC2015下运行,没有考虑线程同步的情况。
一、QThread的使用
QThread是Qt中所有线程控制的基础。每个QThread实例表示并控制一个线程。QThread的使用有2种方式:
- 继承QThread,重写run。
- QObject::moveToThread。
1.继承QThread,重写run
使用这种方式的时候,QThread实例存在于实例化它的旧线程中,而run()在新线程中执行。这意味着QThread的槽都将在旧线程中执行。如下面代码中的WorkerThread::thread接口,打印的是构造WorkerThread的线程,而run里面打印的新的线程。即使我通过connect接口连接这个槽也是一样的,比如MainWindow中有一个按钮,把按钮的clicked信号的workerThread的thread连接起来。
class WorkerThread : public QThread
{
Q_OBJECT
public:
WorkerThread(QObject *parent);
public slots:
void printThread();
void stop();
signals:
void resultReady(const QString &result);
// QThread interface
protected:
virtual void run() override;
private:
bool m_stop;
};
WorkerThread::WorkerThread(QObject *parent)
: QThread (parent)
, m_stop(false)
{
}
void WorkerThread::printThread()
{
qDebug() << "Thread1:" << currentThread();
}
void WorkerThread::stop()
{
m_stop = true;
}
void WorkerThread::run()
{
qDebug() << "Thread2:" << currentThread();
while (!m_stop) {
static int i = 0;
emit resultReady(QString::number(i++));
msleep(1000);
}
}
///////////////////////////////////////////////////////////////////////////
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
WorkerThread *workerThread = new WorkerThread(this);
connect(workerThread, &WorkerThread::resultReady, this, &MainWindow::handleResults);
workerThread->start();
workerThread->thread();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handleResults(const QString &result)
{
qDebug() << "result:" << result;
}
2.QObject::moveToThread
在这种方式中,Worker的槽函数中的代码将在一个单独的线程中执行。但是,您可以自由地将Worker的槽函数连接到任何线程中任何对象的任何信号。由于队列连接的机制,跨不同线程连接信号和槽是安全的。在下面的这个示例中,MainWindow::MainWindow中打印的线程和Worker::thread中打印的线程是不一样的。也就是说Worker::thread中的代码是在另外一个线程中执行的。
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
public slots:
void thread();
};
Worker::Worker(QObject *parent) : QObject(parent)
{
}
void Worker::thread()
{
qDebug() << QThread::currentThread();
}
/////////////////////////////////////////////////
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThread *workerThread = new QThread(this);
Worker *worker = new Worker;
worker->moveToThread(workerThread);
connect(ui->pushButton, &QPushButton::clicked, worker, &Worker::thread);
connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
qDebug() << QThread::currentThread();
workerThread->start();
}

最低0.47元/天 解锁文章
3243





