본문 바로가기

코딩/Python

[Python/파이썬] PyQt5를 통한 GUI 구성 및 사용법 이해하기

반응형

※ 이 글을 쓰는 사람은 SW 비전공자입니다.

※ 개인 공부를 위해 정리하는 글이며, 작성한 코드들은 효율성, 깔끔함(?) 등과는 거리가 멀 수 있습니다.

 

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 사용법


  이번에 해보려는 부분은 PyQT와 동작 함수를 연동시키는 것이다.  어떤 동작 함수가 있고 시작 버튼에 따라 루프를 돌며 동작한다. GUI에서는 진행 상황을 Text 창에 실시간으로 출력해주고 아래 진행막대(0%~100%)를 통해 수치로 보여준다.

 

  먼저 Designer를 통해 GUI를 구성하였다. Designer 프로그램은 이전 편에도 설명하였지만 GUI를 쉽게 구성할 수 있게 만든 PyQT 도구이다. 실행해보면 프로그램 왼쪽에 아래와 같이 위젯 상자 메뉴가 있는데 그냥 드래그해서 Dialog 창에 놓으면 위젯이 추가된다.

 

< 위젯상자 >

 

1. Dialog 및 Widget  설명

 

  내가 만드려는 test 프로그램을 위해 Dialog에 3개의 위젯을 추가하였다.(PushButton, TextBrowser, ProgressBar)  밑에 그림을 보면 알겠지만 각각 Class Name과 Objet Name을 가지고 있다. 

 

Desinger를 통해 구성한 GUI

 

 

-. ClassName : 밑에 코드에서 설명하겠지만 PyQT에서 다루는 다이얼로그 창, 각 위젯(시작 버튼, 텍스트창, 진행 막대)는 각각의 Class를 가지고 있다. PyQT5의 QtWidget이라는 모듈에 포함되어 있는 Class이다.

 

-. ObjetName : 각 위젯들은 객체명(고유의 이름)을 가지고 있다. Class 정리편에서 설명하였지만 각 클래스의 속성을 가지고 있는 인스턴스들인 것이다. 파이썬 코드에서는 이 객체명을 가지고 코딩을 하니 잘 기억해두자!

 

 

  위에서 정리한 ClassName과 ObjetName을 알려면 Designer 창에서 우측에 있는 객체 탐색기 메뉴와 속성 편집기 메뉴를 확인하면 된다.

< Designer 툴의 오른쪼겡 표시되어있는 객체 탐색기 ,속성 편집기 >

 

  위 GUI를 구성하고 저장해보았다. 이전편에도 설명했던 부분인데 designer를 통해 저장하면 아래 이미지처럼 .ui 확장자 파일이 저장된다. 

 

< .ui 확장자 파일 저장 >

 

 

2. 파이썬 연동

 

  : test 로 작성한 전체 코드는 하단에 있으니 참고!!

 

 

  1) pyqt 모듈 import 및 만든 designer 파일 연동하기

  

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic


#UI파일 연결
#단, UI파일은 Python 코드 파일과 같은 디렉토리에 위치해야한다.
form_class = uic.loadUiType("test_pyqt.ui")[0]

 

pyqt 모듈은 QTWidgets 모듈과 uic 모듈을 import 하면 된다. PyQt5.QTwidgets 모듈 안에는 각 위젯에 대한 Class들을 확인할 수 있다. (아래 이미지 참고)

 

< PyQT5.QtWidgets 안의 클래스들)

 

  파이썬 코드랑 연동하는 방법은 1편에서 2가지 방법을 소개했었는데 이번 편에서는 .ui파일을 PyQt5의 uic 모듈을 통해 직접 파일명으로 연동시키는 법을 활용하였다.

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

 

아래 코드 한줄 넣고 GUI Class에서 form_class를 상속받으면 끝난다.(아래 3) 코드의 WindowClass에서 상속시키면 됨)

 

form_class = uic.loadUiType("test_pyqt.ui")[0]
print(form_class) #form_class는 Ui_Dialog라는 class이다.


# 결과 : <class 'Ui_Dialog'>

 

  - 위 코드는 작성하고 있는 .py파일과 .ui 파일이 같은 경로에 있을 때만 적용된다.

 

  - ui 파일의 경로가 다른 겨우 uic.loadUiType("경로\파일명.ui")를 넣어주면 된다.

 

 - .ui 파일명을 직접 입력하여 연동하는 방법은 designer로 GUI 배치, 구성을 자주 변경 해야할 경우 좋다. 직접 사용해보니 파일명만 똑같이 같은 경로에 저장하면 프로그램에 바로 반영 된다.

 

 - 단, designer에서 수정이 안되는 부분은 세부 코드로 구현해야 하는데 .ui파일(xml)을 직접 수정하거나 .py파일로 변경하여 수정해야 한다.

 

 

2) GUI Class 정의 및 실행 코드

 

#메인 윈도우 클래스
class WindowClass(QMainWindow, form_class) :
    #초기화 메서드
    def __init__(self) :
        super().__init__()
        self.setupUi(self)
        #pushButton (시작버튼)을 클릭하면 아래 fuctionStart 메서드와 연결 됨.
        self.pushButton.clicked.connect(self.functionStart) 

    # 시작버튼을 눌렀을 때 실행되는 메서드
    def functionStart(self):
      self.progressBar.setRange(0, 19) #progressbar 초기 설정(100을 0~19, 20단계로 나눔)
      for i in range(0, 20):
            print("출력 : ",str(i))
            self.progressBar.setValue(i) #progress bar 진행률 올리기
            self.textBrowser.append("출력 : "+str(i)) #text browser 문자열 추가하기
            
#코드 실행시 GUI 창을 띄우는 부분
#__name__ == "__main__" : 모듈로 활용되는게 아니라 해당 .py파일에서 직접 실행되는 경우에만 코드 실행
if __name__ == "__main__" :
    app = QApplication(sys.argv)
    myWindow = WindowClass()
    myWindow.show()
    app.exec_()

 

-. 위에서 정의한 form_class와  QTWidget 모듈에 있는 QMainwidow 클래스를 상속받는다.

-. 1번 Designer 내용에서 다뤘지만 파이썬 코드에서 위젯상자에 대한 코드를 작성하려면 ObjectName으로 접근해야 한다.

(pushButton, progressBar, textBrowser)

-. 위 ObjectName에 대해 접근하려면 QtWidget 모듈이 import 되어 있어야 한다.

-. 각 Object(Class)에 대한 속성 설정 및 사용법은 아래 링크를 참고하였다.

(위키독스 - '초보자를 위한 Python GUI 프로그래밍-PyQt5 참고링크 : wikidocs.net/book/2944)

 

 -. 코드 하단의 if 문은 Class에서 구성한 GUI 창을 직접 윈도우에서 실행시키고 보여지게 하는 부분임.

 

 

3) 실행 결과

 

  시작 버튼을 누르면 아래와 같이 textbrowser 창에 내용이 출력되고, ProgressBar가 움직이는 것을 확인할 수 있다.

 

 

< 결과 > 

 

4) 전체 코드

 

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

#UI파일 연결
#단, UI파일은 Python 코드 파일과 같은 디렉토리에 위치해야한다.
form_class = uic.loadUiType("test_pyqt.ui")[0]

#메인 윈도우 클래스
class WindowClass(QMainWindow, form_class) :
    #초기화 메서드
    def __init__(self) :
        super().__init__()
        self.setupUi(self)
        #pushButton (시작버튼)을 클릭하면 아래 fuctionStart 메서드와 연결 됨.
        self.pushButton.clicked.connect(self.functionStart) 

    # 시작버튼을 눌렀을 때 실행되는 메서드
    def functionStart(self):
      self.progressBar.setRange(0, 19) #progressbar 초기 설정(100을 0~19, 20단계로 나눔)
      for i in range(0, 20):
            print("출력 : ",str(i))
            self.progressBar.setValue(i) #progress bar 진행률 올리기
            self.textBrowser.append("출력 : "+str(i)) #text browser 문자열 추가하기

#코드 실행시 GUI 창을 띄우는 부분
#__name__ == "__main__" : 모듈로 활용되는게 아니라 해당 .py파일에서 직접 실행되는 경우에만 코드 실행
if __name__ == "__main__" :
    app = QApplication(sys.argv)
    myWindow = WindowClass()
    myWindow.show()
    app.exec_()

 

  위 프로그램은 간단하지만 실제 어떤 기능을 가진 프로그램과 위 GUI를 연동시키려면 쓰레드에 대한 개념을 활용해야 된다고 한다. 기본적으로 파이썬 프로그램은 순서대로 코드가 실행돼서 GUI랑 함수를 동시에 동작하게 하려면 쓰레드를 써야 한다. 파이썬에는 기본적으로 Threading이라는 모듈을 제공하며, PyQt5에서 GUI 쓰레드 구현을 위한 QThread라는 클래스를 제공한다.(Pyqt5의 QtCore라는 모듈에 있는 클래스임)

 

  다음에는 Qthread를 실제 코드에 적용하는 방법을 정리할 예정이다.

 

 

 


참고링크 : 

위키독스 - '초보자 를 위한 Python GUI 프로그래밍-PyQt5'  wikidocs.net/book/2944)

 

 

 

 

728x90