Programming,  Python

[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를 다시 갱신해준다.

Leave a Reply

Your email address will not be published. Required fields are marked *