[PySide2] 1. 기본동작원리

Jay
6 min readJun 24, 2020

1. 시작과 끝

import sys
from PySide2 import QtWidgets
app = QtWidgets.QApplication(sys.argv) #시작
[...]
sys.exit(app.exec_()) #끝

여기서 QApplication 은 Qt App 객체, 즉 “프로그램”을 만들기위한 하나의 큰 바구니를 생성하게 된다. 그런데 이 객체를 생성만 하면, python은 “나는 할 일 다했어.” 라고 생각을 하고 프로그램을 종료하는데, 나는 이 프로그램이 종료되길 원하는 것이 아니라, 내가 어떠한 명령을 취할때 그에 맞는 행동을 해주길 기대하기 때문에, 대기 상태에 있어야 한다. 즉 프로그램이 꺼지면 안되는데, 이를 구현하기 위해 무한 루프상태로 만들게 되는데 그것이 바로 app.exec_() 이다. execute의 약자이며, app이 종료되면 0을 return한다.

이 return된 0을 sys.exit(0)로 받으면 python은 루프에서 빠져나와 정상종료를 하게된다. 따라서, 가장 기본적인 개념은 프로그램을 만들기 위해

app생성
app무한루프

무한루프 탈출 시 →정상종료 sys.exit(0)

여기서 QApplication생성시 sys.argv가 인자로 들어가게되는데,

저것을 프린트해보면

import sysprint(sys.argv)

위와같이 현재 작업중인 .py파일의 절대경로를 인자로 넣어주는 것을 알 수 있다. 이는 QApplication이라는 객체가 실행할 파일이 현재 파이썬 코드라는것을 알려주는 것으로 생각할 수 있을 것 같다. 이러한 개념을 이해하면, 절대적으로 앱생성과 종료코드를 main 코드에 포함시켜줘야함을 알 수 있다.

2. 단순 오브젝트 생성해보기

import sys
from PySide2.QtWidgets import *
app = QApplication(sys.argv)
label = QLabel("Hello Qt for Python!")
label.show()
sys.exit(app.exec_())

위의 시작과 끝 사이에 QLabel오브잭트를 생성하고 Label을 붙여준 뒤에 오브잭트를 show 하고 종료할때 나오는 모습이다.

튜토리얼 t1.py에서는

import sys
from PySide2 import QtWidgets
app = QtWidgets.QApplication(sys.argv)btn= QtWidgets.QPushButton("Hello world!")
btn.show()
sys.exit(app.exec_())

버튼을 생성하여 보여주고있다 (아무일도 일어나진 않는다)

3. 시그널/슬롯개념에 대하여

일단 PySide2 tutorial 2의 t2.py의 코드를 조금 더 단순화 하면

import sys
from PySide2 import QtCore, QtWidgets
app = QtWidgets.QApplication(sys.argv)btn = QtWidgets.QPushButton("Quit")QtCore.QObject.connect(btn, QtCore.SIGNAL("clicked()"), app, QtCore.SLOT("quit()"))btn.show()sys.exit(app.exec_())

실제 생성되는 오브젝트는 위의 2번과 다른 점이 없지만,

QtCore.QObject.connect(btn, QtCore.SIGNAL("clicked()"), app, QtCore.SLOT("quit()"))

이 코드가 추가되었는데,

이를 잘 살펴보면 QtCore.QObject 모듈에서 connect function을 통해

btn의 clicked()를 시그널로, app의 quit()을 슬롯으로 사용하여 버튼이 클릭될때 앱의 종료함수가 동작하도록 시그널/슬롯을 연결해준 것을 알 수 있다.

아주 기본적인 개념으로써 GUI프로그래밍 전반에 걸쳐서 가장 많이 사용될 기능중에 하나일 것으로 추측하고있다.

4. 클래스생성/위젯상속

이제 PySide2 tutorial 4의 t4.py를 좀 더 단순화 시켜서 보면

import sys
from PySide2 import QtCore, QtWidgets
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.btn = QtWidgets.QPushButton("Quit", self)
self.connect(self.btn, QtCore.SIGNAL("clicked()"),
qApp, QtCore.SLOT("quit()"))
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())

이렇게 쓸 수 있는데,

위젯class를 상속받은 새로운 MyWidget클래스를 만들고, 위에서 QtCore.Object.connect를 widget이 기본적인 매소드로 가지고 있어 self.connect로 대체할 수 있음을 볼 수 있다.

여기서 또하나 눈 여겨볼 점은 qApp을 정의하지 않았는데도, 무리없이 애러가 뜨는데, 그 이유는 이미 QtWdiget에 qApp을 정의 하고 있기 때문으로 추측된다.

코드를 이렇게 구성하게되면 차후에

if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())

로 코드 말미에 깔끔하게 구성해줄 수 있을것으로 판단됨.

--

--

Jay

Brain Neural Network : Where neuroscience meets machine learning