본문 바로가기
GUI 튜토리얼/PySide6 # Qt의 원조가 돌아왔다!

1. PySide6의 Signal과 Slot에 관하여

by 일코 2021. 3. 25.

시그널과 슬롯

짐작컨대 이 몇 개 안 되는 튜토리얼 시리즈를 따라오시면서, 여러분이 가장 많이 하셨던 생각 중 하나는,

"그래서 이 버튼이 뭔가 액션을 하게 하려면 어떻게 해야 하나?"

일 거라고 생각합니다. 지금까지 QWidget이나 QMainWindow 혹은 (QWidget을 상속한) QMainWindow를 상속한 MainWindow라는 클래스를 통해서도 GUI윈도우를 만들어봤고, 창 안에다 푸쉬버튼도 하나 넣어봤는데 이제 이 버튼이 뭔가 작동하게 만들어볼 시간이 되었습니다.

뭔가 작동하게 하는 코드는 굉장히 간단합니다. 이걸 알려드리기 전에, 시그널과 슬롯이라는 용어에 대해서 먼저 설명드리려고 합니다.

지금 우리가 원하는 건,

지금 우리가 원하는 건 "버튼을 눌렀을 때", "뭔가 작동한다" 입니다.

직관적으로 표현해보면, 버튼을 눌렀을 때 발생하는 특정 신호를 통해 특정 메서드(또는 함수)를 실행하게 하고 싶습니다. 그리고 Qt는 정확히 이 방식으로 작동합니다. 굉장히 직관적이죠 Qt에서는 이 때 발생한 신호를 "시그널", 실행되는 서드(함수)를 "슬롯"이라고 부릅니다. 용어도 간단하지 않나요?ㅎ

시그널과 슬롯에 대한 더 좋은 비유나 설명이 인터넷에 참 많습니다. 저는 그 중에서도 임덕규님의 파이콘코리아2015 발표내용을 가장 좋아합니다. "시그널과 슬롯은 커플이예요. 왜냐면..." 이 뒷부분이 궁금하시면 아래 유튜브링크를 참고해주세요.

https://youtu.be/UHqZMRbHcvc?t=1365

너무 뽕만 넣지 말자는 의미에서 한 가지 말씀드리면, Qt가 많이 쓰이는 이유가 "Qt의 시그널-슬롯 개념이 다른 GUI 프로그래밍보다 훨씬 간편하고 재미있어서"라기보다는, 이식성이 좋고, 배포가 쉬워서라는 전문가 분들의 의견이 있더라고요. (저도 틈틈이 C# 윈폼으로 GUI 그리기도 연습하고 있는데, 많이 닮아있는 것 같기도 합니다.)

 

하여튼 아주 간단한 시그널-슬롯 예제를 보여드릴테니, 따라해보시면서 개념에만 익숙해지시면 좋겠습니다. (너무 간단하다고 이 예제를 무시하지는 말아주세요^^ 머릿속에서 반짝~ 하면서 만들어 보고 싶은 GUI가 무궁무진하게 떠오르는 분들도 분명 계실 거라는 생각이 듭니다.)

 

새 py파일을 하나 만들고 아래의 내용을 보면서 타이핑한 후 실행해봅시다.

 

임포트문과 빈줄 포함 12줄입니다. 금방 타이핑 가능하시죠?

 

참고로 위의 코드는 아래처럼 클래스로 작성하실 수도 있습니다. 참고로 보여드리겠습니다.

 

위의 코드를 클래스 방식으로 바꾸어보았습니다. 비슷해 보이죠?

 

기왕이면 두 마리 토끼를 잡자.

제 바람은, 둘 다 반복하면서 코딩과 파이참 기능 모두 익숙해지는 연습을 하시면 좋겠습니다. 예를 들면, 저는 Ctrl-Shift-Enter(자동완성 후 줄바꿈)이나 Ctrl-Space(자동완성) 등의 단축키를 즐겨 사용합니다. 

사실, 코드를 곰곰이 떠올리면서 타이핑하는 경우라면 자동완성을 쓰든 안쓰든 속도차이가 거의 없을텐데, 어느 정도 Qt 코딩에 익숙해져 있거나, 머릿속에 이미 코드가 완성되어 있는 경우라면 코딩속도가 몇 배씩 빨라집니다. 한 번 보여드릴게요.

 

기본적인 뼈대(항상 반복하는 라인)은 자동완성 떡칠을 해줍시다.

 

이런 식으로 반복되는 코드 패턴은 단축키 쓰듯 자동완성을 많이 이용하시면, 눈에 보일만큼 코딩이 빨라질 겁니다. 중요하지 않은 부분 같지만, 이런 툴을 최대한 활용하려고 의식적으로 노력하신다면 분명 생산성에도 큰 향상이 있을 것입니다.

코드실행

하여튼, 코드를 실행해보면 다음과 같습니다.

 

버튼을 클릭할 때마다 "Clicked!"를 출력합니다.

 

- 3번라인에 간단한 함수 button_is_clicked()를 하나 생성했습니다. 이 함수가 곧 슬롯이 됩니다. 

- 그리고 9번라인 보시면 button.clicked시그널입니다.

- 시그널과 슬롯을 연결하는 가장 기본적인 방법은 시그널.connect(슬롯)입니다.

그리고, 슬롯과 연결된 시그널만 실제 작동합니다.

슬롯과 연결된 시그널만 작동한다. 이게 무슨 말이냐고요? 실제로 발생은 하지만, 허공에서 사라지는 시그널도 있을 수 있다는 뜻입니다. 사실 방금도 허공에 외치고 사라진 시그널이 여러 개 있었습니다. 그 중에 하나만 예를 들면, 버튼을 클릭할 때 발생하는 .clicked 직후에 클릭한 버튼을 뗄 때 발생하는 .released 시그널이 있었죠. released 시그널에도 새로운 슬롯 하나 연결해서 다시 실행해볼게요.

 

시그널 두 개에 각각 슬롯 하나씩을 연결해보았습니다.

 

직접 실행해보셨나요? 예상하셨던 방식과 미묘하게 다르다고 느끼는 분들도 계실텐데요. 클릭&릴리즈는 이 방식으로 동작하는 게 맞습니다. 누르는 시점에 시그널이 뜨고 놓는 시점에 시그널이 뜨는 방식을 사용하고 싶은 분은 clicked 대신 pressed 시그널을 사용하시면 정확히 원하시는 방식대로 구현될 것입니다.

 

마우스버튼을 누르는 시점에 Pressed, 놓는 시점에 Released가 발생합니다.

 

여기까지는 "특정 시그널(clicked, released, pressed)를 슬롯(파이썬함수)에 연결"하는 기초예제였다고 보시면 됩니다.

다음포스팅 예고 : 시그널-슬롯, 어떻게 응용할 수 있을까?

위에서 특정 시그널을 우리가 정의한 파이썬 함수와 연결하여 어떤 액션을 취하게끔 해보았습니다. 이걸 뼈대삼아 여러가지 응용방법을 생각해볼 수 있습니다. 다음 포스팅에서 세 가지 정도만 다뤄보려고 합니다.

 

1. 특정 변수에 상태를 저장하여 현재 상태에 따라 파이썬 if문 등을 통해 다른 액션을 취하게 하는 방법. (On/Off 토글스위치 등.)

 

2. 슬롯(함수) 안에 위젯의 인터페이스를 변경하는 커맨드를 입력하는 방법(특정 버튼 비활성화, 또는 숨기기 등)

 

3. 시그널을 (파이썬 함수 슬롯을 거치지 않고) 직접 다른 위젯과 연결(다이얼버튼과 숫자, LineEdit와 Label 연결 등)

 

이번 포스팅에서 모두 다뤄보려고 했는데, 너무 늘어지는 것 같아서 여기서 한 번 끊고 갑니다.

 

다음 포스팅에서 뵙겠습니다.

행복한 하루 되세요!

 

이 포스팅을 위해 참고한 자료

 

PyQt5 tutorial 2021 — Create GUI applications with Python and Qt

Learn Python GUI programming with hands on tutorials and examples. Build your own apps with PyQt5.

www.learnpyqt.com

 

Signal과 slot 연결 기본 - 예제로 배우는 PyQt

Signal과 slot 연결하는 방법을 예제를 통해 알아보자 예제보기

opentutorials.org

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

 

 


donaricano-btn

댓글