[PyQt5] PyQt5 Tutorial
해당 글은 [PyQt5 Tutorial - 파이썬으로 만드는 나만의 GUI 프로그램]을 공부한 내용을 바탕으로 하며, 자세한 내용 및 소스코드는 하단 링크를 참조한다.
PyQt5
- Qt : 플랫폼에 관계 없이 다양한 기능을 포함하는 C++ 라이브러리 & 개발툴
- PyQt5 : Qt5 어플리케이션 프레임워크의 Python 모듈 모음
기초 사용법
창 띄우기 및 기본 구조
PyQt5.QtWidgets: 기본적 UI 구성요소 제공 클래스가 포함된 모듈- PyQt5 어플리케이션은 어플리케이션 객체를 생성해야 하므로
QApplication클래스의 변수를 할당
import sys
from PyQt5.QtWidgets import QApplication, QWidget
class MyApplication(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Application Title')
#창의 제목표시줄에 나타날 제목
self.move(300, 300)
#스크린 상에서 위젯이 나타날 위치(x방향[px], y방향[px])
self.resize(400, 200)
#위젯의 크기 (너비[px], 높이[px])
self.show()
#위젯을 화면에 띄움
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApplication()
sys.exit(app.exec_())
창을 가운데에 띄우기
move()함수 위치에 지정한 새 함수를 이용해 위치를 설정함
def center(self):
window_info = self.frameGeometry() #창의 위치와 크기 정보 받음
center_loc = QDesktopWidget().availableGeometry().center()
#사용자의 모니터 가운데 위치 파악
window_info.moveCenter(center_loc) #중심 위치를 지정한 곳으로 이동
self.move(window_info.topLeft()) #현재 창의 위치를 지정한 곳으로 이동
Main Window(메인 창)
- 메뉴바, 툴바, 상태바를 갖는 어플리케이션 창
QMenuBar,QToolBar,QDockWidget,QStatusBar위한 고유 레이아웃 가짐- 중간 영역에 중심위젯(Central Widget)을 위한 영역 가짐. 모든 위젯이 들어올 수 있음
Layout (레이아웃)
- Layout(레이아웃) : 어플리케이션 창에 위젯들을 배치하는 방식. 창을 그리는 함수 부분 이전에 코드 작성함
- 절대적 배치(Absolute Positioning) : 위젯의 위치 및 크기를 픽셀 단위로 설정해 배치하는 방법. 창의 크기와 위젯의 크기&위치는 연동되지 않음
btn = QPushButton('Button', self) #버튼 객체 생성 btn.move(80, 13) #(가로, 세로) 위치에 버튼 위치시킴 - 박스 레이아웃(Box Layout)
QHBoxLayout,QVBoxLayout클래스 : 여러 위젯을 수평/수직으로 정렬. 다른 레이아웃 박스를 넣거나 위젯을 배치 가능addStretch(): 필요 공간 확보.stretch factor로 비율 조절- 창의 크기를 변화시켜도 같은 자리에 위치
okButton = QPushButton('OK') cancelButton = QPushButton('Cancel') hbox = QHBoxLayout() #수평 박스 생성 hbox.addStretch(1) #왼쪽에 공간 확보 hbox.addWidget(okButton) #버튼 넣기 hbox.addWidget(cancelButton) hbox.addStretch(1) #오른쪽에 공간 확보 vbox = QVBoxLayout() #수직 박스 생성 vbox.addStretch(3) #위쪽에 공간 확보 vbox.addLayout(hbox) #수평 박스룰 수직 박스 안에 넣기 vbox.addStretch(1) #아래쪽에 공간 확보 self.setLayout(vbox) #수직박스를 메인 레이아웃으로 설정 - Grid Layout(그리드 레이아웃)
- 가장 일반적 레이아웃으로, 위젯 공간을 행과 열로 구분.
QGridLayout클래스 사용
grid = QGridLayout() #그리드 레이아웃 생성 self.setLayout(grid) #창의 메인 레이아웃으로 설정 grid.addWidget(QLabel('Text Rabel'), 0, 0) #라벨 객체를 0행 0열에 배치 grid.addWidget(QLineEdit(), 0, 1) #텍스트 편집 객체를 0행 1열에 배치
Widget (위젯)
QPushButton(버튼), QLabel(텍스트/이미지 라벨), CheckBox(체크박스), QLineEdit(텍스트 편집기), QGroupBox(그룹박스), QSpinBox(정수 선택 및 조절), QTableWidget(표) 등의 위젯이 있어 이를 배치하여 화면을 구성
Signal & Slot (시그널 & 슬롯)
-
Signal & Slot (시그널 & 슬롯) : 이벤트 처리에 사용되는 매커니즘. 시그널은 이벤트 발생을 알리고 슬롯은 이를 처리함
-
연결하기
lcd = QLCDNumber(self) #숫자 LCD 스타일로 표시하는 객체 dial = QDial(self) #다이얼 객체 dial.valueChanged.connect(lcd.display) #QDial 위젯 객체의 시그널에 연결 # valueChanged() 시그널을 lcd 객체의 display 슬롯에 연결 # display 슬롯은 숫자를 받아 QLCDNumber 위젯에 표시 -
이벤트 핸들러(slot)
- 이미 클래스 내에 만들어진 핸들러 함수 있음
- 사용자 정의 시그널
class Communicate(QObject): close_app_signal = pyqtSignal() #시그널 class MyApplication(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.c = Communicate() #시그널 클래스 할당 self.c.closeApp.connect(self.close) #연결 self.setWindowTitle('Emitting Signal') self.setGeometry(300, 300, 300, 200) self.show() def mousePressEvent(self, e): self.c.closeApp.emit() #마우스 클릭 시 closeApp 시그널 방출
Painting(그림 그리기)
-
PyQt5.QtGui의QPainter클래스 : 그리기 기능 제공하는 클래스. 위젯의 Paint Event로 동작이 주로 이루어짐 -
점 그리기(draw_point)
import sys from PyQt5.QtWidgets import QWidget, QApplication from PyQt5.QtGui import QPainter, QPen from PyQt5.QtCore import Qt class MyApp(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(300, 300, 400, 300) self.setWindowTitle('Points') self.show() def paintEvent(self, e): qp = QPainter() #QPainter 객체 생성 qp.begin(self) #QPainter 객체 시작 self.draw_point(qp) #그리기 함수 qp.end() #그리기 종료 def draw_point(self, qp): qp.setPen(QPen(Qt.blue, 8)) #QPen 객체 할당 및 크기 설정 qp.drawPoint(self.width()/2, self.height()/2) #위치 설정 #또는 # pen = QPen() # colors = ['#D83C5F', '#3CD88F', '#AA5CE3', '#29ACF2'] # for i in range(1000): # pen.setWidth(np.random.randint(1, 15)) # pen.setColor(QColor(np.random.choice(colors))) # qp.setPen(pen) # rand_x = 100 * np.random.randn() # rand_y = 100 * np.random.randn() # qp.drawPoint(self.width() / 2 + rand_x, self.height() / 2 + rand_y) if __name__ == '__main__': app = QApplication(sys.argv) ex = MyApp() sys.exit(app.exec_()) -
직선 그리기 (draw_line)
def draw_line(self, qp): qp.setPen(QPen(Qt.blue, 8)) #선의 색과 두께 설정 또는 QPen의 Qt.DashLine처럼 선 스타일 설정 qp.drawLine(30, 230, 200, 50) #(첫 점의 x, y, 두번째 점의 x, y)순으로 양 끝점 위치를 정수로 입력 qp.drawText(30, 90, 'Qt.DashLine') #선에 레이블 할당
실행파일 만들기
PyInstaller로 Python과 PyQt5로 만든.pyGUI 프로그램을.exe파일로 변환 가능PyInstaller패키지 설치pip install pyinstaller- 실행파일 만들기
.py파일이 있는 폴더로 이동 후 명령프롬프트 열어 명령어 입력 :pyinstaller 파일이름.py- 폴더 내
dist폴더로 이동하면 실행파일 존재. 오픈 시 콘솔창이 켜지며 GUI 실행파일 실행 - 콘솔창 출력되지 않도록 하려면 명령어에
-w옵션 추가 - 다른 파일 없이 실행파일 하나만 생성하려면 명령어에
-F또는-onefile옵션 추가
참고자료
댓글은 Disqus 로 제공됩니다.