이번 글에서는 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에 대해 알아보았습니다.