[Qt] QThread

이번 글에서는 Qt 에서 QThread를 사용하는 방법에 대해 알아보겠습니다.

QThread는 QTimer와 다르게 신호를 발생시키지 않고, 별도의 쓰레드를 생성하여 특정 작업을 수행합니다.

QThread에서 자주 사용하는 함수들은 아래와 같습니다.

  • start: 쓰레드 시작
  • wait: 쓰레드 끝 날때까지 대기
  • quit: 쓰레드를 강제로 종료
  • terminate: 쓰레드를 강제로 종료
  • isRunning: 쓰레드가 run 중인지
  • isFinished: 쓰레드가 종료됐는지


MyThread 클래스 생성

쓰레드를 시작했을 때 작업할 내용을 구현하려면 QThread 클래스를 상속받는 클래스를 하나 생성한 뒤, run 함수를 재정의 해야합니다.

[프로젝트 우클릭]-[Add New]를 선택해줍니다.

그다음 [C/C++]-[C++ Class]를 선택해줍니다.

아래 그림과 같이 MyThread, QThread, Add Q_OBJECT 설정 해주시고 클래스를 생성해줍니다.

MyThread 코드 작성

MyThread가 정상적으로 생성 되면 아래와 같이 MyThread.h에 가상 함수 run을 선언 합니다.

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();

private:
    virtual void run();
};

#endif // MYTHREAD_H

MyThread.cpp에 아래와 같이 가상 함수 run을 정의 합니다.

#include "mythread.h"

#include <QDebug>
#include <QCoreApplication>

MyThread::MyThread()
{
}

void MyThread::run()
{
    qDebug() << "========== start thread";

    for (int i = 0 ; i < 10 ; i++)
    {
        qDebug("========== count: %d", i);
        msleep(1000); // 1초(1000msec) 슬립
    }

}

main에 아래와 같이 MyThread를 사용합니다.

#include <QCoreApplication>

#include <QObject>
#include <QDebug>
#include <QThread>

#include "mythread.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread mythread;
    qDebug() << "isRunning: " << mythread.isRunning(); // run?
    qDebug() << "isFinished: " << mythread.isFinished(); // Finished?

    mythread.start();
    qDebug() << "isRunning: " << mythread.isRunning(); // run?
    qDebug() << "isFinished: " << mythread.isFinished(); // Finished?

    mythread.wait(); // 종료할 때까지 대기
    qDebug() << "isRunning: " << mythread.isRunning(); // run?
    qDebug() << "isFinished: " << mythread.isFinished(); // Finished?

    return a.exec();
}

실행하면 아래와 같이 출력합니다.

isRunning:  false
isFinished:  false
isRunning:  true
isFinished:  false
========== start thread
========== count: 0
========== count: 1
========== count: 2
========== count: 3
========== count: 4
========== count: 5
========== count: 6
========== count: 7
========== count: 8
========== count: 9
isRunning:  false
isFinished:  true

QThread 시그널 함수

isRunning, isFinished 함수 말고 QThread 시그널 함수를 사용하는 방법도 있습니다.

  • started: 시작 시그널 함수
  • finished: 종료 시그널 함수

아래 두 함수를 만들어 주고 main에서 connect 해줍니다.

// Thread 시작 시그널을 받기위한 함수
void slot_started()
{
    qDebug() << "--- slot function: " << Q_FUNC_INFO;
}

// Thread 종료 시그널을 받기위한 함수
void slot_finished()
{
    qDebug() << "--- slot function: " << Q_FUNC_INFO;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
	
	// ...
	
	QObject::connect(&mythread, &MyThread::started, slot_started); // 쓰레드 시작 signal 함수 연결
	QObject::connect(&mythread, &MyThread::finished, slot_finished); // 쓰레드 종료 signal 함수 연결

	// ...
	
    return a.exec();
}

실행하면 아래와 같이 표시됩니다.

--- slot function:  void slot_started()
========== start thread
========== count: 0
========== count: 1
========== count: 2
========== count: 3
========== count: 4
========== count: 5
========== count: 6
========== count: 7
========== count: 8
========== count: 9
--- slot function:  void slot_finished()

전체 코드는 아래 링크를 참고하시길 바랍니다.

https://github.com/3001ssw/qt_cpp_study/tree/main/020QThread

이상으로 QThread에 대해 알아보았습니다.