前言 假如将一些耗时操作放在UI线程处理,会导致UI卡顿,影响用户使用体验。因此,我们通常会将耗时操作放在新的线程中处理。这就涉及到线程的使用。在qt中,有几种方式启动多线程:
继承QThread,重新实现run()函数
使用QObject::moveToThread()函数
使用QtConcurrent模块
具体实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 // 1. 继承QThread class DemoThread : public QThread { Q_OBJECT public: explicit DemoThread(QObject *parent = 0); ~DemoThread(); protected: //QThread的虚函数,不能直接调用,通过start()间接调用 void run(); signals: //处理完成信号 void processFinished(); }; #endif // MYTHREAD_H }; void DemoThread::run() { // 在该函数中进行业务的耗时操作 // doSomething //发送完成信号 emit processFinished(); } // 2. 通过QObject::moveToThread() --- qt assistant 提供的例子 class Worker : public QObject { Q_OBJECT public slots: void doWork(const QString ¶meter) { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &result); }; class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Worker *worker = new Worker; worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::operate, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResults); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } public slots: void handleResults(const QString &); signals: void operate(const QString &); }; // 3. 使用QtConcurrent模块 // 3.1 不需要处理结果 QtConcurrent::run(this, &Controller::doWork, params); // 3.2 需要接受处理结果 QFutureWatcher<QVariantMap> *doWorkWatcher = new QFutureWatcher<QVariantMap>; QFuture<QVariantMap> future = QtConcurrent::run(this, &Controller::doWork, params); connect(doWorkWatcher, &QFutureWatcher<QVariantMap>::finished, [=]() { QVariantMap result = doWorkWatcher->resultAt(0); doWorkWatcher->deleteLater(); }); doWorkWatcher->setFuture(future);
其他补充 从上边三种方式来说,QtConcurrent的方式相对简单和直观。QtConcurrent是在Qt 4.4开始引入的。当然,作为一个高级api,除了直接调用run外,QtConcurrent还提供了很多的函数适用于其他的应用场景的。这在之后的文章,会详细介绍。