QSocketNotifier 클래스는 파일 디스크립터의 활동 모니터링을 지원한다.
리눅스 또는 유사 시스템에서 어떤 주변장치를 주기적으로 엑세스했던 경우 QSocketNotifier 클래스를 사용하면 간단하게 활동을 감지할 수 있다.
즉, 시스템콜 API를 호출하여 장치를 열고 socket notifier를 통해 파일 디스크립터를 모니터링 할 수 있다.
socket notifier는 해당 소켓 이벤트가 발생할 때마다 activated()시그널을 발생하며 이 스그널에 연결할 슬롯을 구현하면 된다.
아래 간단한 예제 소스코드를 보자.
키보드 장치의 이벤트를 읽는 슬롯을 구현한 클래스이다.
#include <QObject>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>
class KbdHandler : public QObject
{
Q_OBJECT
public:
explicit KbdHandler(QObject *parent)
: QObject(parent),
m_fd(-1){
}
virtual ~KbdHandler(){
}
bool setFileDescriptor(int fd){
if(fd < 0)
return false;
m_fd = fd;
return true;
}
int fileDescriptor(){
return m_fd;
}
private Q_SLOTS:
void readData(){
input_event ev;
if(read(m_fd, &ev, sizeof(input_event))){
qDebug() << "code: " << ev.code;
if(EV_KEY != ev.type)
return;
if(ev.value == 1){
qDebug() << "down";
}else{
qDebug() << "up";
}
}
}
private:
int m_fd;
};
QSocketNotifier를 생성시에는 읽기, 쓰기 또는 둘 모두의 유형으로 설정해야한다.
Constant |
Value |
Description |
QSocketNotifier::Read |
0 |
There is data to be read. |
QSocketNotifier::Write |
1 |
Data can be written. |
QSocketNotifier::Exception |
2 |
An exception has occurred. We recommend against using this. |
KbdHandler *handler = new KbdHandler(&a);
if (handler->setFileDescriptor(open("/dev/input/event1", O_RDONLY | O_NONBLOCK, 0))) {
qDebug() << handler->fileDescriptor();
auto m_usbnotify = new QSocketNotifier(handler->fileDescriptor(), QSocketNotifier::Read);
QObject::connect(m_usbnotify, SIGNAL(activated(int)), handler, SLOT(readData()));
}else{
return -1;
}
.
.
.
// 사용이 끝나면 닫는 걸 잊지 않도록 한다.
close(handler->fileDescriptor());
delete handler;
Qt의 메인 이벤트 루프에서 검출되므로 별도의 이벤트 루프를 생성하지 않아도 된다.