파이큐티의 윈도우창을 생성할 수 있게 되었다면 그 다음은 위젯을 사용해 볼 차례다.
가장 보편적인 위젯은 역시 레이블과 버튼이다.
우리는 일상생활에서 GUI를 너무 많이 쓰기때문에 이미 익숙해져 버렸다.
그러다 보니 GUI의 본질에 대하여는 잊어버린 상태로 기계적으로 코딩을 한다.
사용자들이 핸드폰을 가지고 무엇을 하는가를 한 번 생각해보자.
그들은 여러가지를 한다. 게임을 하기도 이메일을 확인하거나 인터넷 검색을 하다가 유튜브를 본다.
이 모든 행동의 공통점이 있다. 사용자들이 화면에 있는 무언가를 보고 판단에 따라 터치(클릭)하여 조작하는 행위를 반복하는 것이다. 그 무언가는 텍스트, 즉 레이블이고 터치하는 것은 버튼을 말한다.
물론 영상이나 그림을 보고도 조작할 수 있다. 그러나 사람들의 행동을 이끄는 것은 한 마디의 지시어나 물음 같은 것이다. '다음 페이지에 무슨무슨 내용이 있습니다', '클릭하면 결제 페이지로 넘어갑니다'
즉 사용자는 스마트폰을 사용하면서 이런 것도 저런 것도 하면서 시간을 보내지만 판단하고 결정해야할 순간이 왔을 때 레이블에 써있는 핵심 정보나 지시사항을 읽고 판단하여 적절한 버튼을 누르는 것이다.
기술적으로 보면 레이블은 터치했을 때 이벤트 핸들링하는 기능이 없고, 버튼은 터치에 대응하는 이벤트 핸들러가 있다. 그것만 빼면 둘다 화면상에 보여지는 좌표일 뿐이다. 같은 특성을 공유하는 부분이 있다는 것은 메소드와 멤버변수의 구성이 호환된다는 말이기도 하다. 위젯 하나를 사용할 수 있으면 다른 비슷한 위젯은 쉽게 사용할 수 있다.
그런 이유로 레이블과 버튼은 중요하다. PyQt5에서는 QLabel, QPushButton 클래스로 표현되었다.
위젯이 있다면 그것을 담을 레이아웃도 있어야 한다. PyQt의 레이아웃에는 다양한 종류가 있지만 처음부터 모든 레이아웃을 다 알필요는 없다. 가장 자주 사용하는 것을 사용하다 보면 익숙해지기 마련이다.
VBoxLayout 은 위에서 아래로 내려오는 레이아웃이다. 가로로 가는 레이아웃은 HBoxLayout 이다. 이렇게 이름이 자기 자신을 잘 나타내는 것은 좋은 작명이다.
그럼 소스코드를 보면서 알아보자.
* 객체지향언어의 소스코드는 위에서 부터 읽으면 힘들다. 잘 읽혀지지도 않고 그보다는 부분을 나눠서 읽는게 좋다. 규모에 따라 나눠서 읽으면 수월하다. 소스코드도 '읽는 책' 이라고 생각해도 된다. 컴퓨터는 잘 읽는데 인간에게는 좀 딱딱한 책일 뿐이다...
from PyQt5.QtWidgets import QWidget, QApplication, \
QLabel, QVBoxLayout, QPushButton
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.setUp()
def setUp(self):
label = QLabel("Good Question 1")
label.setAlignment(Qt.AlignCenter)
label.setFont(QtGui.QFont('Hack', 20))
label2 = QLabel("slept well?")
label2.setAlignment(Qt.AlignCenter)
label2.setFont(QtGui.QFont('Hack', 20))
label3 = QLabel("if not, go get some sleep!")
label3.setAlignment(Qt.AlignCenter)
label3.setFont(QtGui.QFont('Hack', 20))
button = QPushButton("no I want to play~")
button.setFont(QtGui.QFont('Hack', 20))
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(label2)
layout.addWidget(label3)
layout.addWidget(button)
self.setLayout(layout)
self.setWindowTitle("First Window PyQt5")
self.setGeometry(300, 300, 500, 400)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
root = Window()
sys.exit(app.exec_())
* import 문을 사용하는 좋은 방법은 PyCharm 을 사용하는 것이다. 다른 어떤 IDE 보다 PyCharm은 Python 을 위해 태어난 IDE기 때문에 (이름이 벌써 Py다) 편리성이 뛰어나다. 파이썬을 사용하는 많은 이들이 항상 추천하는 IDE다.
import문에 하나씩 입력하면 시간이 오래걸리고 어렵다. 귀찮으면 첫번째 줄을 import * (모든 모듈) 하는 방법도 있다. 이 방법을 쓴다고 성능이 나빠지거나 하지는 않는다. 초보일 때는 * 방법도 권장한다. 다만 그렇게 하면 몇개의 모듈을 사용하고 있는건지 감이 떨어져서 필자의 경우는 10개 이하는 하나씩 import 한다.
나머지는 코딩을 하던 도중 아래와 같이 빨간줄이 뜰 때 클릭하면 자동으로 import 한다.
* 초기화 부분은 파이큐티5 시작하기 포스팅에서 설명을 했는데 QWidget의 부모 생성자를 호출하면 QWindow 의 메소드를 사용할 수 있게 한다. 코드가 복잡해지기 전에 나머지 프로시저는 메소드로 넘겼다.
여기는 CPU가 윈도우 창을 만드는 작업장이다. 많아 보이지만 아래처럼 나눠 놓으면 심플하다. 레이블 3개와 버튼 1개를 수직 레이아웃인 QVBox 에 넣은 윈도우를 정의한다. 각 메소드의 이름과 속성을 보면 자기 자신을 설명하고 있다. 자세한 것을 설명하지 않아도 충분하다.
이 세줄은 파이큐티의 구조를 나타낸다.
어플의 인스턴스를 생성하고 클래스에 정의한 윈도우의 인스턴스를 생성한다. (위의 위젯들을 모아놓은 조립품이다)
윈도우 루프를 실행하고 종료시 exit 한다.
레이블과 버튼을 레이아웃에 올렸다면 하나의 스테이지를 클리어한 것이다. 그 다음에 할 것은 이 위젯을 아름답게 꾸미고 원하는 위치에 배치하는 것이다. 위치에 관해서는 레이아웃을 더 사용해보면 될 것이고 꾸미는 것으 폰트 메소드를 사용하고 배경색상 등 그래픽적 요소를 더 사용하는 것이다.
이 튜토리얼에서 모든 것을 자세히 설명하지는 않는다. 모든 것을 설명하면 그건 레퍼런스(사전)가 되고 잘 들여다 보지 않는다. 튜토리얼의 가이드를 잘 따라가면 나중에는 스스로 자립할 힘을 얻을 것이다. 너무 매달릴 필요도 없고 지금은 몰라도 되니까 필요할 때 마다 검색하면 된다.
중요한 것은 튜토리얼 자습서가 아니라 자신의 프로젝트니까 그렇게 활용하면 좋을 것 같다. 최근에는 코딩에 관련해서 유튜브 영상들을 많이 본다고 하는데 필자의 생각은 영상을 많이 봐도 자기가 짠 코드가 없으면 아무 소용이 없다고 생각한다. 대학교 입시에는 좋은 강의를 많이 듣는게 좋다. 그런데 코딩은 실전이므로 강의를 듣는 것도 중요하지만 모든 것을 직접 실행해보는 것이 좋다.
파이큐티5 같은 GUI 라이브러리는 이것을 가지고 놀기가 좋다. 게다가 파이썬이니까 코드 몇개만 조합을 하면 빠른 결과물이 나온다. tkinter 의 경우 라이브러리 자체가 오래되고 기능에 제한이 있었지만 파이큐티는 그에 비해 훨씬 환경이 좋다.
PyQt를 일이나 공부라 생각하지 않고 장난감이라 생각하면 빠르게 습득할 것 이다.
PyQt5-tutorial/PyQtQLabelQButton.py at main · kayken7/PyQt5-tutorial (github.com)