본문 바로가기

코딩/Python

[Python/파이썬] PyQt5 - 시그널(Signal)과 슬롯(Slot) 개념

반응형

 

  pyqt를 공부하면서 Thread에 대한 내용을 정리한 적이 있다. Thread는 프로세스 내 여러 개의 동작을 동시에 할 수 있다고 하였다. 즉, GUI가 멈추지 않고 다른 동작을 할 수 있게 코드를 작성할 수 있다.


※ 참고링크

1편 : 2021.03.06 - [코딩/Python] - [Python/파이썬] PyQT5 및 QT Designer 소개, .ui 파일 .py로 변환 방법

2편 : 2021.03.28 - [코딩/Python] - [Python/파이썬] PyQt5를 통한 GUI 구성 및 사용법 이해하기

3편 : 2021.03.29 - [코딩/Python] - [Python/파이썬] PyQt5 사용시 필요한 쓰레드 개념 이해 - 1

4편 : 2021.03.30 - [코딩/Python] - [Python/파이썬] PyQt5 사용시 필요한 쓰레드 개념 이해-2 (GUI 응답없음 해결)

5편 : 2021.07.19 - [코딩/Python] - [Python/파이썬] PyQt5 - 시그널(Signal)과 슬롯(Slot) 개념

6편 : 2021.07.22 - [코딩/Python] - [Python/파이썬] PyQt5 - 사용자 정의 시그널(Custom Signal)과 Emit 사용법

 


  Thread에서 좀 더 고급 내용으로 들어가면 Thread간 통신을 하는 내용이 나온다. 어떤 내용이냐면, Thread 가 각각 자신의 동작을 할뿐만 아니라 Thread 간 통신을 해서 상호작용한다는 것이다.(데이터를 실시간으로 클래스간 주고받는 등) 조금 어려운 내용이긴 한데 알고 있으면 나중에 좀 더 어려운 프로그램을 만드는데 도움이 될 것 같아 정리해보려고 한다.

 

  Thread 간 통신을 다루기 전에 먼저 PyQt5에서 시그널(Signal)과 슬롯(Slot)의 개념을 알아야 한다. 시그널이란 다른 말로 이벤트(Event)라고도 하는데 GUI에서 어떤 행동을 이야기 한다. 예를 들면, '마우스를 클릭한다', '버튼을 누른다', '콤보박스의 목록을 선택한다' 등 여러가지를 예를 들 수 있다.

 

  슬롯(Slot)은 이벤트 핸들러(Event Handler)라고 부르기도 한다. 말 그대로 '어떤 이벤트가 발생했을 때, 프로그램 상에서 실제 어떤 처리를 할거냐'라는 부분이다. 'GUI 창에서 x버튼을 누르면 창이 꺼진다', '파일찾기 버튼을 누르면 경로 탐색기가 열린다' 등의 예를 들 수 있겠다.

 

  아래 코드를 통해 이해해보자. 얼마 전에 포스팅했던 콤보박스 GUI이다. 전체 코드는 아래 링크를 참고하면 되고, 이번 포스팅에서는 해당되는 내용만 일부 발췌하여 정리했다.

(참고링크 : 2021.07.07 -  [파이썬/업무자동화] PyQt5 콤보박스 응용 - 엑셀 시트 리스트를 콤보박스화하기)

 

 

< 엑셀 선택 후, 콤보박스에 시트명 출력하기 >

  

 

  위 결과 이미지 예시를 시그널(Signal)과 슬롯(Slot)으로 구분해보도록 하자.

 

 

 

1. '엑셀 파일 선택' 버튼 클릭 - Signal(시그널)

 

 

<코드>

#fileSelect 버튼 클릭 : Signal // selectFunction 메서드 : Slot
self.fileSelect.clicked.connect(self.selectFunction)

 

  위 부분은 fileSelect라는 객체(엑셀 파일 선택 버튼)를 클릭했을 때, selectFunction이라는 메서드를 동작시키는 코드이다. 위에서 self.fileSelect.clicked.connect( )라는 부분이 시그널(또는 이벤트)라고 이해하면 된다. selectFunction은 아래 설명하겠지만 시그널에 따라 실제 처리하는 슬롯(또는 이벤트 핸들러)이다.

 

 

 

2. 버튼 클릭 후, 경로 탐색기를 통해 엑셀 파일 선택 - 슬롯(Slot)

 

 

  <코드>

 #selectFunction 메서드 정의
    def selectFunction(self):
        .
        .
        .
        #선택한 엑셀 파일 경로를 받아옴 : 튜플 타입으로 받아오며 0번재 요소가 주소값 string이다.
        path = QFileDialog.getOpenFileName(self, 'Open File', '', 'All File(*);; xlsx File(*.xlsx)')
        #filePath에 현재 읽어온 엑셀 파일 경로를 입력한다.(절대경로)
        self.filePath.setText(path[0])

        #위 절대 경로 활용해 openpyxl workbook 객체 생성
        wb = op.load_workbook(path[0])
        #설정한 workbook의 시트리스트를 읽어온다.
        self.shtlist = wb.sheetnames
        print(self.shtlist)
        
        #시트리스트를 반복문으로 진행
        for sht in self.shtlist:
            #콤보박스의 addItem을 사용하여 항목 추가(addItem의 요소는 문자열 타입)
            self.comboBox.addItem(sht)

 

 

  엑셀파일을 선택해서 경로를 GUI에 출력하고 엑셀파일의 시트 리스트를 콤보박스에 출력하는 코드이다. 이 부분이 fileSelect(버튼)에 대한 슬롯을 구현한 것이라고 이해하면 된다.

 

 

 

3. 콤보박스 변경하는 행동 - 시그널(Signal) / 터미널에 콤보박스 내용 출력 - 슬롯(Slot)

 

 

 

 

  콤보박스도 '엑셀 파일 선택' 찾기 버튼과 마찬가지로 구분할 수 있다. 콤보박스에서 목록을 변경하는 행동은 시그널(또는 이벤트)라고 할 수 있다. 그래서 콤보박스도 객체명 comboBox를 통해 시그널은 슬롯에 연결하는 코드가 있다.

 

 

<코드>

#comboBox 변경 : Signal // printShstName 메서드 : Slot
self.comboBox.currentIndexChanged.connect(self.printShtname)

 

 

  코드 그대로 이해해보면 comboBox가 currentIndexChanged(목록이 변경될 때마다)라는 시그널에 따라 printShtname 메서드라는 슬롯에 연결된다는 의미이다. 따라서, 슬롯을 구현한 코드는 아래와 같다.(printShtname 메서드)

 

 

<코드>

#콤보박스의 내용 변경시 터미널에 시트명 출력 : Slot 구현
def printShtname(self):
	print(self.comboBox.currentText())

 

 

  위에서 다룬 내용은 사실 PyQt5에서 기본적으로 제공하는 object들에 따른 것이다. 실제 Thread간 통신을 구현할 땐, 사용자 정의 시그널(Signal)이라는 것을 많이 사용한다. 간단히 설명하자면, 내가 정의 한 클래스를 시그널로 사용하여 연결한 슬롯에 데이터를 전달할 수 있다는 것이다. Signal과 emit이라고 검색하면 나오는 내용인데 이렇게 설명하기에는 어려워서 다음 편에서 공부하여 정리할 예정이다.

 

 


참고링크 : 위키독스 - 파이썬을 이용한 비트코인 자동매매(개정판) 중 03-7 https://wikidocs.net/21876

 

위키독스

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

wikidocs.net

 

 

 

728x90