[Python] PyQt
Python에서 GUI를 지원하기 위해 가장 많이 사용하는 library는 PyQt다.
import sys from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import Qt class Form(QWidget): def __init__(self): QWidget.__init__(self, flags=Qt.Widget) self.init_widget() def init_widget(self): self.setWindowTitle("Hello World") if __name__ == "__main__": app = QApplication(sys.argv) form = Form() # From QWidget form.show() exit(app.exec_())
결과는 위와 같이 단순한 창 하나가 나온다.
QWidget의 속성 얻기
Widget이라고 하면 하나의 창을 말하는 것 같은데, 해당 속성들을 쉽게 얻는 코드가 아래에 있다.
import sys from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QLabel from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import Qt class Form(QWidget): def __init__(self): QWidget.__init__(self, flags=Qt.Widget) self.lb = None self.init_widget() def init_widget(self): self.setWindowTitle("Hello World") self.setGeometry(100, 100, 640, 480) self.lb = QLabel(self) properties_list = ( "width", "height", "x", "y", "geometry", "maximumHeight", "maximumWidth", "maximumSize", "minimumSize", "minimumWidth", "size", "windowFilePath", "windowTitle" ) msg = self.get_properties_value(properties_list) self.lb.setText(msg) def get_properties_value(self, properties): msg = [] for p in properties: if not hasattr(self, p): continue value = getattr(self, p)() msg.append("{:>20s} : {:<30s}".format(p, str(value))) msg = "\n".join(msg) return msg if __name__ == "__main__": app = QApplication(sys.argv) form = Form() form.show() exit(app.exec_())
얻고자 하는 속성들의 문자열 list를 properties_list
에 담아서 get_properties_value(properties_list)를 통해 함수로 전달하는게 보인다.
for p in properties: if not hasattr(self, p): continue value = getattr(self, p)() msg.append("{:>20s} : {:<30s}".format(p, str(value))) msg = "\n".join(msg) return msg
각 속성 문자열에 대해 만약 유효한 속성일 경우 20칸을 기준으로 오른쪽으로 정렬하며, 콜론 우측의 경우엔 30칸을 잡고 왼쪽으로 정렬하라는 의미다. 그리고 최종 문자열을 리턴하게 된다. 리턴한 문자열을 self.setText()
통해 출력하게 된다.
실시간으로 값 변경하기
PointEvent
를 이용해 실시간으로 마우싀 포인터 위치의 값을 받아와 출력하는 코드를 소개한다.
import sys from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QLabel from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import Qt class Form(QWidget): def __init__(self): QWidget.__init__(self, flags=Qt.Widget) self.mouse_x = 0 self.mouse_y = 0 self.lb = QLabel(self) self.properties_list = ( "width", "height", "x", "y", "geometry", "maximumHeight", "maximumWidth", "maximumSize", "minimumSize", "minimumWidth", "size", "windowFilePath", "windowTitle", "underMouse" ) self.init_widget() def init_widget(self): self.setWindowTitle("Hello World") self.setGeometry(100, 100, 640, 480) self.setMouseTracking(True) self.lb.setStyleSheet("background-color: yellow") self.lb.setMouseTracking(True) msg = self.get_properties_value(self.properties_list) self.lb.setText(msg) def get_properties_value(self, properties): msg = [] for p in properties: if not hasattr(self, p): continue value = getattr(self, p)() msg.append("{:>20s} : {:<30s}".format(p, str(value))) msg.append("{:>20s} : {:<30s}".format("mouse_x", str(self.mouse_x))) msg.append("{:>20s} : {:<30s}".format("mouse_y", str(self.mouse_y))) msg = "\n".join(msg) return msg def mouseMoveEvent(self, QMouseEvent): self.mouse_x = QMouseEvent.x() self.mouse_y = QMouseEvent.y() self.update() def moveEvent(self, QMoveEvent): self.update() def paintEvent(self, QPaintEvent): msg = self.get_properties_value(self.properties_list) self.lb.setText(msg) if __name__ == "__main__": app = QApplication(sys.argv) form = Form() form.show() exit(app.exec_())
기존 코드와 차이점은 self.setMouseTracking(True)
이 사용되어 실시간으로 마우스 위치를 tracking한다. 배경 색은 self.lb.setStyleSheet("background-color: yellow")
를 통해 변경하며 label 위에서도 마우스 위치가 tracking되어야 하기 때문에 self.lb.setMouseTracking(True)
를 선언해줘야 한다.
마우스가 움직일 때 값을 업데이트를 해줘야하기 때문에 mouseMoveEvent(self, QMouseEvent)에 마우스의 x, y 좌표의 값을 전달해준다.
self.update()를 하면 화면이 갱신된다.
paintEvent(self, QPaintEvent)
는 self.update()
가 되면서 화면이 갱신되면서 호출된다. 이 때 새로 업데이트된 msg
를 다시 갱신해준다.