QT/VS based QT

Qt Signal/Slot 을 이용한 이벤트 호출

kahuz 2020. 8. 2. 23:12

본 포스팅은 프로젝트 QILT를 진행하며 알게 된 소소한 팁을 기록하기 위한 포스팅입니다.

 

Qt Signal/Slot

 - Qt에서 제공하는 오브젝트간의 통신 시스템을 의미

 - 한 문장으로 표현하면 " A 오브젝트에서 Signal이 발생하면 B 오브젝트의 Slot을 호출하여라 " 이다.

 - 글쓴이는 Qt 개발의 짬(?)이 부족하여 상세한 내용을 제외하고 Qt에서 제공하는 Qt Designer를 이용하여 사용하는 방법과 개발자가 커스텀하여 사용하는 두 방법에 대해 설명할 것이다

 - 초심자가 보기 쉽게 설명은 스크린샷으로 진행, 사용된 코드는 맨 하단에 git gist로 제공할 것이다.

 

프로젝트 생성

 - 본 작성글은 Qt Widget 프로젝트를 이용해 진행된다

Fig1. Qt Widget 프로젝트 생성

 - Signal/Slot을 사용하기 위해서는 Signal/Slot을 등록/호출 할 Widget Class와 ui파일만을 사용한다

Fig2. 생성된 프로젝트

Qt Designer를 이용한 Signal/Slot 사용 방법

 - 본 글에서는 QMenu의 Item을 클릭하였을때 프로그램(MainWindow)가 종료되는 예제를 설명한다. 해당 예제를 이용하여 다양하게 활용해보도록 하자.

 - Fig2 사진의 QtSignalSlot.ui 파일을 실행하면 아래와 같이 Qt Designer가 실행될 것이다

Fig3. ui 파일 실행 모습

- 간단한 예제를 위해 QMenuBar(menuBar)에 menu item을 하나 생성한 뒤 등록되어 있는 signal과 slot을 이용하는 방법을 설명할 것이다

- Fig3을 보면 "여기에 입력하십시오"라고 나와 있는 부분이 QMenuBar(menuBar) 부분으로, 더블클릭 후 텍스트를 입력하고 엔터를 누르면 QMenu가 생성되는 것을 알 수 있다.

- 그 뒤 생성된 QMenu를 클릭하여 나오는 "여기에 입력하십시오"를 더블클릭하여 텍스트를 입력하면 QAction 또한 자동으로 생성된다.

 

Fig4. QMenu와 QAction 생성

- QMenu는 일반적인 프로그램의 메뉴바에서 상위 메뉴 아이템을 의미하며, QAction은 하위 메뉴 아이템을 뜻한다고 생각하면 된다.

- QAction은 특정한 event(Signal)이 발생될때 등록된 함수(Slot)을 실행하는 역할을 하는 아이템이다

- Fig4의 하단을 보면 시그널/슬롯 편집기가 있는 것이 확인할 수 있다.

- Qt 프레임워크는 이곳에서 시스템에 등록된 오브젝트( Widget, Action, etc ...)에 Qt 시스템이 제공하는 기본적인 event(Signal)과  함수(Slot)을 이용해 특정 동작을 구현할 수 있도록 제공한다.

 

Fig5. Signal/Slot 생성

 - Fig5와 같이 시그널/슬롯 편집기의 " + " 아이콘을 클릭하면 새로운 Signal/Slot을 생성할 수 있다.

 - 여기서 송신자는 Signal이 발생할 오브젝트로 예제에서는 Fig4에서 생성한 "Window exit" Action이 된다

 - 시그널은 송신자가 어떠한 event(trigger)를 받았음을 확인하는 역할로 대표적으로 Button의 Press()나 Action의 Trigger()가 존재한다. 자세한 것은 Qt Documentation을 확인하자

 - 수신자는 송신자가 시그널이 발생했을때 호출할 함수의 오브젝트( Widget, Action, Item, etc ... ) 를 의미한다. 예제에서는 MainWindow를 종료할 것이기에 수신자는 MainWindow가 된다.

 - 슬롯은 수신자가 송신자로부터 시그널이 발생했음을 확인받았을때 실행할 함수를 의미한다. 예제에서는 MainWindow를 종료하기 위해 close 함수를 등록할 것이다.

Fig6. Signal/Slot 등록

- 여기서 송신자와 수신자를 선택할 때는 아래 Fig7에서 볼 수 있듯이 객체 탐색기에서 시그널/슬롯을 등록할 오브젝트의 이름을 찾아 시그널/슬롯 편집기에서 선택하면 된다.

 

Fig7. 시그널 편집기의 등록된 모습과 객체 탐색기에 나타난 오브젝트 이름들

이로써 시스템에 등록된 Signal/Slot 등록 과정이 끝났다. 참 간단하죠?

이대로 프로그램을 실행시켜 Window exit 아이템을 클릭하면 프로그램 창이 종료되는 것을 확인할 수 있다.

 

Fig8. 프로그램 실행 모습. Window exit를 클릭하면 QtSignalSlot 창이 종료된다

다만, 이대로 끝내기에는 실제 프로젝트에서 활용하기에 너무도 빈약한 정보이다.

 

중요한 것은 개발자 Signal/Slot을 커스텀하여 원하는 함수를 자유롭게 호출하는 방식이라고 생각한다.

 

Signal/Slot 사용자 정의 방법

 - 본 글에서는 위와 같이 QMenu에서 QAction을 하나 생성하여 QMessageBox를 띄우는 예제를 설명한다. 해당 예제에서 Slot에 등록될 함수를 자유롭게 수정하면 이제 당신도 Signal/Slot을 활용할 줄 안다고 할 수 있다!

 

 - 우선 Qt Designer에서 등록된 내용이 저장되는 ui_'메인 클래스 이름'.h 파일을 살펴보자

 - 아래 Fig9와 같이 생성된 Qt 프로젝트의 메인 클래스의 헤더파일에 선언된 Ui 네임스페이스를 ctrl + 클릭을 통해 파일을 확인할 수 있다 ( 정의로 이동 )

Fig9. ui_'메인 클래스 이름'.h 파일을 찾아간 모습

 - ui_'메인 클래스 이름'.h 파일을 잘 살펴보면 QObject::connect ... 으로 선언된 내용을 확인할 수 있을 것이다.

 - 이 부분이 바로 위에서 Qt Designer를 이용해 생성한 시그널/슬롯 동작을 코드로 작성된 부분이다.

 - 우리는 이 방법과 유사한 방법으로 메인 클래스에서 특정 QMenu item을 선택하면 QMessage Box를 호출하도록 함수를 만들고 Signal/Slot을 등록할 것이다.

 - 우선은 Signal을 발생시킬 QMenu item을 하나 생성하도록 한다

Fig10. QMessageBox를 호출할 QAction을 하나 생성한다

- 위와 같이 생성한 뒤 프로젝트를 실행하고 나면 ui_메인 클래스.h 에 QMessageBox를 위한 QAction 변수가 생성되는 것을 확인할 수 있다.

 

Fig11. 생성된 QAction을 확인

 - 그 다음 Fig9 내용에서 설명했던 것 ui_메인 클래스.h에 작성되어있던 Signal/Slot 함수 호출 코드를 활용해 사용자 정의 Signal/Slot을 작성한다.

 -> 1. Signal/Slot을 등록할 Class Header파일에 Slot 함수를 등록한다. 예제에서는 " void on_triggered_menu_QMessage() " 라는 함수를 등록할 것이다

Fig12. 사용자 Slot 함수 등록

 - Fig12를 보면 private slots: 이라는 키워드를 등록하였는데, 이것은 Qt Framework에 해당 Qt클래스에 slot 함수를 등록할 것을 알리기 위함으로 생각하면 된다.

 - slots 키워드를 통해 선언한 함수는 해당 Qt클래스 파일에 내용을 정의해주면 된다.

Fig13. 사용자 Slot함수 정의

* 중요한 점 1. Fig12의 코드 line 8 을 확인하면 Q_OBJECT 키워드가 선언되있는 볼 수 있다. 이처럼 Q_OBJECT가 선언되어있어야 signal/slot 등록이 가능하며

** 중요한 점 2. 사용자 함수를 정의할때 송신자 클래스 멤버함수로 정의하여야한다.

   이 말인 즉, Fig13의 line 11과 같이 retrun_type Class :: Function_name(Param) 와 같이 Class 부분이 시그널을 받을 송신자 클래스여야 한다는 뜻이다.

 

- 마지막으로 선언/정의한 함수를 connect 함수로 signal/slot 등록을 해주면 된다. 가급적 클래스 생성자에서 등록하기를 권하는 바이다.

Fig14. 사용자 slot함수 등록

- connect 함수의 매개변수는 다음과 같은 의미를 가진다

   - connect ( param 1 , param2, param3, param4 );

   - param 1 : 송신자 매개변수로 signal을 발생시킬 오브젝트를 의미한다.

   - param 2 : signal 함수, 예제의 SIGNAL(triggered())는 Qt에서 제공하는 기본 시그널 함수로, QAction 아이템을 클릭할때 발생된다. 자세한 것은 Qt Documentation을 참고하자

   - param 3 : 수신자 매개변수로 여기서 this는 QtSignalSlot 클래스 자체를 의미. 즉, 프로그램에서 MainWindow를 담당하는 객체가 되는 것이다

   - param 4 : slot 함수, signal 함수가 발생했을때 호출될 함수로 본 예제에서는 QMessageBox를 띄우는 사용자 정의 함수를 등록하였다.

 

예제 결과

Fig15. 예제 결과

 

이처럼 방법만 알면 Qt Signal/Slot을 활용하는 것은 매우 손쉽게 이용할 수 있다.

다만 글쓴이는 Qt에 관련된 책이나 강의를 듣지 않고 Qt Documentation과 구글링만을 이용해 프로젝트를 개발하다보니 시간이 좀 걸린 부분이었기에 내용을 남기는 바이다

 

'QT > VS based QT' 카테고리의 다른 글

OpenCV 이미지를 QT로 출력하기 ( C++)  (0) 2020.07.23
Visual Studio 2019 QT 환경설정  (2) 2020.07.23