상세 컨텐츠

본문 제목

[PySide6] QFrame과 QColorDialog 사용하기

pyside6

by 빨간눈동자 2021. 9. 2. 10:40

본문

반응형

Unbuntu 환경에서도 Window 그림판과 비슷한 기능을 하는 "KolourPaint" 프로그램이 존재한다.

이 프로그램에는 글씨 및 도형(Object) 색상의 변경을 지원하는 기능이 존재한다. ( 노란색 Box )

해당 기능을 PySide6로 간단하게 구현해보도록 하자. 

import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QColorDialog
from PySide6.QtGui import QColor
from PySide6.QtCore import QObject, Signal, QEvent

def mySignal(widget):
    class Filter(QObject):     
        clicked = Signal()

        def eventFilter(self, obj, event):
            if obj == widget:
                if event.type() == QEvent.MouseButtonRelease:
                    if obj.rect().contains(event.pos()):
                        self.clicked.emit()
                        return True

            return False

    filter=Filter(widget)
    widget.installEventFilter(filter)
    return filter.clicked

class MyApp(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        col = QColor(0xFF, 0xFF, 0xFF)

        self.frm = QFrame(self)
        self.frm.setStyleSheet('QWidget { background-color: %s }' % col.name())
        self.frm.setGeometry(50, 50, 100, 100)
        self.frm.setFrameShape(QFrame.WinPanel)
        self.frm.setFrameShadow(QFrame.Raised)
        mySignal(self.frm).connect(self.showDialog)

        self.setWindowTitle('Color Dialog')
        self.setGeometry(300, 300, 200, 180)
        self.show()

    def showDialog(self):
        col = QColorDialog.getColor()

        if col.isValid():
             self.frm.setStyleSheet('QWidget { background-color: %s }' % col.name())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec())

실행 초기 화면
흰 영역 클릭 시 생성되는 QColorDialog
색 선택 후, 변경된 모습

 

  • setStyleSheet()을 이용하면, Widget에 다양한 style을 적용할 수 있다.  ( 아래 링크 참조 ) 

 

code 를 살펴보도록 하자 

    def initUI(self):
        col = QColor(0xFF, 0xFF, 0xFF)

        self.frm = QFrame(self)
        self.frm.setStyleSheet('QWidget { background-color: %s }' % col.name())
        self.frm.setGeometry(50, 50, 100, 100)
        self.frm.setFrameShape(QFrame.WinPanel)
        self.frm.setFrameShadow(QFrame.Raised)
        mySignal(self.frm).connect(self.showDialog)

위 code는 dialog 에서 흰색 영역을 생성하는 부분이다. 

QColor()롤 통해 col (0xFFFFFF : 흰색) 을 생성하고, 이를 Style sheet 를 사용하여 배경을 흰색으로 설정하였다. 

이후, setGeometry()를 통해 영역의 크기를 결정하였다. 

setFrameShape() 와 setFrameShadow()는 흰영역에 3D 입체감을 주기 위해 사용해 보았다. 

 

마지막 line은 흰 영역을 클릭할 경우, showDialog() 함수가 호출되도록 하였다. 

참고로 QFrame class는 clickable 속성이 없기 때문에, 사용자 지정 event를 통해 signal과 slot을 연결해 주었다. 

 

def mySignal(widget):
    class Filter(QObject):     
        clicked = Signal()

        def eventFilter(self, obj, event):
            if obj == widget:
                if event.type() == QEvent.MouseButtonRelease:
                    if obj.rect().contains(event.pos()):
                        self.clicked.emit()
                        return True

            return False

    filter=Filter(widget)
    widget.installEventFilter(filter)
    return filter.clicked

mySignal()예 Qframe instance를 인자로 전달하면, Filter() class의 instance를 생성한다. 

Filter()의 eventFilter()는 사용자가 원하는 event를 골라 signal을 발생시킬 수 있다. 

obj, 즉, QFrame 영역에 mouse release event가 발생하면, clicked 라는 signal을 발생하라는 의미로 해석하면 되겠다. 

이후 인자로 넘어온 widget, 즉,  QFrame instance에 해당 filter를 적용한다 ( installEventFilter() ) 

요약하면, QFrame 영역에서 mouse release event가 발생하면 filter.clicked (true)를 return 하게 된다. 

 

필요에 따라서 아래 부분을 변경해주면, 다양한 event를 사용자 정의를 통해 사용할 수 있다. 

if event.type() == QEvent.MouseButtonRelease:

 

반응형

관련글 더보기