이 페이지에서

스타일이 위젯을 그리는 방식

QStyle API에는 세 가지 종류의 함수가 있습니다. 위젯을 그리는 함수, 슬라이더 핸들의 위치 계산과 같은 일반적이면서도 까다로운 작업을 위한 정적 헬퍼 함수, 그리고 위젯이 그려지는 동안 필요한 계산(예: 크기 힌트 계산)을 수행하는 함수입니다. 또한 스타일은 일부 위젯의 콘텐츠 레이아웃을 구성하는 데 도움을 주며, 위젯이 그리는 데 사용하는 그리기 영역( QPalette )을 조정할 수도 있습니다.

이 페이지에서는 스타일 구현이 사용하는 구성 요소들을 설명합니다. ‘위젯 스타일 참조’에는 각 위젯이 어떤 구성 요소를 사용하는지 나열되어 있습니다.

스타일 요소

QStyle 그래픽 요소를 그립니다. 요소란 위젯 또는 위젯의 일부(예: 푸시 버튼의 베벨, 창 테두리, 스크롤 바)를 말합니다. 대부분의 그리기 함수는 네 개의 인자를 받습니다:

  • 그릴 그래픽 요소를 지정하는 열거형 값.
  • 해당 요소를 어떻게, 어디에 렌더링할지 지정하는 위치 및 방향 매개변수( QStyleOption ).
  • 요소를 그릴 때 사용할 QPainter.
  • 그리기가 수행될 대상 QWidget 입니다. 이 인수는 선택 사항입니다.

위젯이 스타일에게 요소 그리기를 요청할 때, 스타일에는 그리기에 필요한 정보를 포함하는 클래스인 ‘ QStyleOption ’가 제공됩니다. 이 ‘option’에는 스타일에 필요한 모든 정보가 포함되어 있으므로, 스타일은 위젯 코드를 연동하지 않고도 위젯을 그릴 수 있습니다. QComboBox 뿐만 아니라 어떤 페인트 장치에서든 콤보 박스를 그릴 수 있습니다.

위젯은 macOS의 애니메이션 기본 버튼과 같은 특수 효과를 위해 스타일에 필요할 경우를 대비해 마지막 인수로 전달되지만, 스타일은 이를 전적으로 의존할 수는 없습니다. 여러 요소를 직접 그리는 위젯은 스스로를 전달하며, ` QStylePainter`도 마찬가지입니다. 페인트 장치에 직접 그리는 코드는 ` nullptr`를 전달할 수 있습니다.

위젯은 스타일 요소들의 계층 구조, 즉 트리로 구성됩니다. 예를 들어, 스타일이 푸시 버튼을 그릴 요청을 받으면 레이블(텍스트 및 아이콘), 버튼 베벨, 포커스 프레임을 그립니다. 버튼 베벨은 다시 베벨을 둘러싼 프레임과 패널로 구성됩니다. 다음 개념적 트리는 푸시 버튼 요소를 그리기 순서대로 보여주며, 중첩된 요소는 그 위의 요소에 의해 그려집니다:

  • 푸시 버튼
    • 버튼 베벨
      • 기본 버튼 프레임
      • 버튼 패널
    • 라벨 (아이콘 및 텍스트)
    • 포커스 프레임

참조 자료의푸시 버튼은 QPushButton 의 실제 트리와 요소 이름을 보여줍니다.

위젯이 스타일에게 반드시 하나의 요소만 그리도록 요청하는 것은 아닙니다. 위젯은 서로 다른 요소를 그리기 위해 스타일에게 여러 번 호출을 보낼 수 있습니다. 예를 들어, QTabWidget 는 탭과 프레임을 개별적으로 그립니다.

요소 유형에는 기본 요소, 컨트롤 요소, 복합 컨트롤 요소의 세 가지가 있습니다. PrimitiveElement, ControlElement, ComplexControl 열거형이 이를 정의합니다. 각 열거형의 값에는 유형을 식별하는 접두사가 붙습니다. 기본 요소는 PE_, 컨트롤 요소는 CE_, 복합 컨트롤은 CC_ 입니다. QStyle 클래스 문서에는 이러한 요소들과 위젯 스타일링에서 각 요소가 수행하는 역할이 나열되어 있습니다.

기본 요소

기본 요소는 여러 위젯에서 흔히 사용되는 일반적인 GUI 요소입니다. 프레임, 버튼 베벨, 스핀 박스, 스크롤 바, 콤보 박스의 화살표 등이 그 예입니다. 기본 요소는 단독으로 존재할 수 없으며, 항상 더 큰 구조의 일부로 존재합니다. 이 요소들은 사용자와의 상호작용에 관여하지 않으며, GUI 내에서 수동적인 장식 역할을 합니다.

컨트롤 요소

컨트롤 요소는 특정 동작을 수행하거나 사용자에게 정보를 표시합니다. 컨트롤 요소의 예로는 푸시 버튼, 체크박스, 테이블 및 트리 뷰의 헤더 섹션 등이 있습니다. 컨트롤 요소가 항상 푸시 버튼과 같은 완전한 위젯인 것은 아니며, 탭 바의 탭이나 스크롤 바의 슬라이더와 같은 위젯의 일부일 수도 있습니다. 컨트롤 요소는 수동적이지 않다는 점에서 기본 요소와 다릅니다. 즉, 사용자와의 상호작용에 직접 참여합니다.

여러 요소로 구성된 컨트롤은 종종 `style`을 사용하여 각 요소의 경계 사각형을 계산합니다. ` SubElement ` 열거형은 사용 가능한 하위 요소를 정의합니다. 이 열거형은 경계 사각형을 계산하는 용도로만 사용됩니다. 하위 요소는 기본 요소, 컨트롤 요소, 복합 요소처럼 그려지는 그래픽 요소가 아닙니다.

복합 컨트롤 요소

복합 컨트롤 요소는 하위 컨트롤을 포함합니다. 복합 컨트롤은 사용자가 마우스로 조작하는 위치와 누르는 키에 따라 다르게 동작합니다. 이는 마우스가 어떤 하위 컨트롤 위에 있거나 어떤 하위 컨트롤이 눌렸는지에 따라 달라집니다. 복합 컨트롤의 예로는 스크롤 바와 콤보 박스가 있습니다. 스크롤 바의 경우 마우스를 사용하여 슬라이더를 이동하거나 위/아래 이동 버튼을 누를 수 있습니다. ` SubControl ` 열거형은 사용 가능한 하위 컨트롤을 정의합니다.

이 스타일은 그리기 기능 외에도, 사용자가 어떤 하위 컨트롤(있는 경우)을 눌렀는지 위젯에 알려줍니다. 예를 들어, ` QScrollBar `는 사용자가 슬라이더, 슬라이더 홈, 또는 버튼 중 하나를 눌렀는지 알아야 합니다.

하위 컨트롤은 컨트롤 요소와 동일하지 않습니다. 스타일을 사용하여 하위 컨트롤을 직접 그릴 수는 없으며, 스타일은 단지 하위 컨트롤이 그려져야 할 경계 사각형을 계산할 뿐입니다. 하지만 복잡한 요소의 경우, 컨트롤 및 기본 요소를 사용하여 하위 컨트롤을 그리는 것이 일반적입니다. Qt의 내장 스타일은 이를 자주 활용합니다. 예를 들어, QCommonStyle 는 PE_IndicatorCheckBox 를 사용하여 그룹 박스 내의 체크박스를 그립니다. 이 체크박스는 CC_GroupBox 의 서브컨트롤입니다. 일부 서브컨트롤에는 이에 상응하는 컨트롤 요소가 있습니다. 예를 들어, 스크롤바 슬라이더(SC_ScrollBarSlider 및 CE_ScrollBarSlider)가 있습니다.

자식 요소, 하위 컨트롤 및 픽셀 메트릭

스타일 요소와 위젯은 스타일을 사용하여 하위 요소 및 하위 컨트롤의 경계 사각형을 계산합니다. 화면 픽셀 단위의 스타일 의존적 크기인 픽셀 메트릭도 그리기 시 측정값으로 사용됩니다. QStyle 에 있는 세 가지 열거형( SubElement, SubControl, PixelMetric)은 사용 가능한 사각형과 픽셀 메트릭을 나타냅니다. 이들의 값은 SE_, SC_, PM_ 으로 시작합니다.

스타일 힌트

이 스타일은 또한 StyleHint 열거형의 값으로 표현되는 일련의 스타일 힌트에 대응합니다. 모든 위젯이 서로 다른 스타일에서 동일한 기능과 외관을 갖는 것은 아닙니다. 예를 들어, 메뉴의 항목이 화면의 한 열에 다 들어가지 않을 때, 일부 스타일은 스크롤을 지원하는 반면 다른 스타일은 모든 항목을 담기 위해 두 열 이상을 표시하기도 합니다. 위젯은 ` styleHint()`를 통해 힌트를 조회합니다.

표준 아이콘

스타일에는 일반적으로 메시지 상자, 파일 대화 상자 및 제목 표시줄 버튼을 위한 경고, 질문, 오류 이미지와 같은 표준 아이콘 세트가 포함됩니다. ` StandardPixmap ` 열거형이 이러한 아이콘의 이름을 지정하며, ` standardIcon()`는 주어진 값에 해당하는 ` QIcon `를 반환합니다. Qt Widgets는 이러한 아이콘을 사용하므로, 스타일을 구현할 때는 해당 아이콘을 제공해야 합니다.

레이아웃 간격

스타일은 레이아웃 내 위젯 간의 간격을 계산합니다. 이러한 계산을 처리하는 방법에는 두 가지가 있습니다. ` PM_LayoutHorizontalSpacing ` 및 ` PM_LayoutVerticalSpacing`에 대해 ` pixelMetric()`에서 간격을 반환할 수 있으며, ` QCommonStyle `이 바로 이를 수행합니다. 또는 더 세밀한 제어가 필요한 경우 ` layoutSpacing()`을 재구현할 수 있습니다. 이 함수에서는 인접한 두 위젯의 컨트롤 유형(QSizePolicy::ControlType), 크기 정책(QSizePolicy::Policy), 그리고 해당 위젯에 대한 스타일 옵션을 기반으로 간격을 계산할 수 있습니다.

스타일 옵션

QStyleOption 의 서브클래스에는 개별 요소의 스타일을 지정하는 데 필요한 모든 정보가 포함되어 있습니다. QStyle 함수를 호출하는 쪽에서는 일반적으로 스택에서 스타일 옵션을 인스턴스화한 후 해당 옵션을 채웁니다. 그려지는 대상에 따라 스타일은 서로 다른 스타일 옵션 클래스를 기대합니다. 예를 들어, PE_FrameFocusRect 요소는 QStyleOptionFocusRect 인수를 기대합니다. 사용자 정의 스타일을 위해 자체 서브클래스를 생성할 수도 있습니다. 스타일 옵션은 성능상의 이유로 공용 변수를 유지합니다.

위젯은 ` State ` 열거형으로 정의된 여러 가지 상태를 가질 수 있습니다. 일부 상태 플래그는 위젯에 따라 의미가 다르지만, ` State_Enabled`와 같이 모든 위젯에 공통적인 것도 있습니다. ` QStyleOption::initFrom()`는 공통 상태를 설정하며, 나머지 상태는 개별 위젯에서 설정합니다.

특히, 스타일 옵션에는 그려질 위젯의 팔레트와 경계 사각형이 포함됩니다. 대부분의 위젯에는 특화된 스타일 옵션이 있습니다. 예를 들어, ` QPushButton `와 ` QCheckBox`는 텍스트, 아이콘, 아이콘 크기를 포함하는 ` QStyleOptionButton`를 사용합니다. ‘위젯 스타일 참조’에서는 각 옵션의 정확한 내용을 설명합니다.

` QStyle ` 함수를 재구현할 때 ` QStyleOption ` 매개변수를 받는 경우, 해당 옵션을 ` QStyleOptionFocusRect`과 같은 서브클래스로 형변환해야 하는 경우가 많습니다. 포인터 유형이 올바른지 확인하려면 ` qstyleoption_cast()`를 사용하십시오. 객체의 유형이 올바르지 않은 경우, ` qstyleoption_cast()`는 ` nullptr`을 반환합니다:

const QStyleOptionFocusRect *focusRectOption =
        qstyleoption_cast<const QStyleOptionFocusRect *>(option);
if (focusRectOption) {
    //...
}

일반적인 상태 플래그 및 멤버

일부 상태와 변수는 모든 위젯에 공통적으로 적용됩니다. 위젯은 ` QStyleOption::initFrom()`를 사용하여 이를 설정합니다. 모든 요소가 이 함수를 사용하는 것은 아닙니다. 위젯은 스타일 옵션을 생성하며, 일부 요소의 경우 ` initFrom()`에서 제공하는 정보가 필요하지 않을 수 있습니다.

상태설정 시점
State_Enabled위젯이 비활성화되지 않은 경우( QWidget::isEnabled() 참조).
State_HasFocus위젯에 포커스가 있을 때( QWidget::hasFocus() 참조).
State_KeyboardFocusChange사용자가 키보드를 사용하여 포커스를 변경한 경우( WA_KeyboardFocusChange 참조).
State_MouseOver마우스 커서가 위젯 위에 있을 때.
State_Active위젯이 활성 창의 자식인 경우.

그 밖의 일반적인 멤버는 다음과 같습니다:

멤버설명
rect그릴 요소의 경계 사각형입니다. ` initFrom() `는 이를 위젯의 경계 사각형(`QWidget::rect()`)으로 설정합니다.
direction레이아웃 방향. ` Qt::LayoutDirection ` 열거형의 값입니다.
palette요소를 그릴 때 사용할 QPalette 입니다. ` initFrom() `는 이를 위젯의 팔레트(`QWidget::palette())`로 설정합니다.
fontMetrics위젯에 텍스트를 그릴 때 사용할 QFontMetrics 입니다.
styleObject이 옵션이 설명하는 객체로, 대개 위젯입니다. 스타일은 이를 사용하여 애니메이션 상태를 저장합니다.

복합 스타일 옵션( QStyleOptionComplex 을 상속하는 클래스)은 subControls 와 activeSubControls 라는 두 가지 변수를 추가로 공유합니다. 두 변수 모두 QStyle::SubControl 값의 OR 조합입니다. 이 변수들은 복합 컨트롤이 어떤 하위 컨트롤로 구성되어 있으며, 그중 현재 어떤 컨트롤이 활성 상태인지를 나타냅니다.

QStyle 함수

QStyle 는 기본 요소, 컨트롤 요소 및 복합 요소를 그리기 위한 세 가지 함수, 즉 drawPrimitive(), drawControl() 및 drawComplexControl()를 정의합니다. 이 함수들은 ‘스타일 요소’ 항목에 나열된 인수를 받습니다.

모든 위젯이 자기 자신에 대한 포인터를 전달하는 것은 아닙니다. 함수에 전달된 스타일 옵션에 필요한 정보가 포함되어 있지 않다면, 위젯 구현을 확인하여 위젯이 자기 자신을 전달하는지 확인하십시오.

QStyle 또한 요소 그리기를 위한 보조 함수들도 제공합니다. ` drawItemText()`는 ` QPalette `를 매개변수로 받아 지정된 사각형 내부에 텍스트를 그립니다. ` drawItemPixmap()`는 지정된 경계 사각형 내부에서 픽스맵을 정렬합니다.

다른 QStyle 함수들은 그리기 함수를 위해 계산을 수행합니다. 위젯들도 여러 스타일 요소를 직접 그릴 때 크기 힌트와 경계 사각형을 계산하는 데 이 함수들을 사용합니다. 이러한 함수들은 일반적으로 그리기 함수와 동일한 인자를 받습니다.

  • subElementRect()는 SubElement 값을 받아 하위 요소의 경계 사각형을 계산합니다. 스타일은 이 함수를 사용하여 요소의 각 부분을 어디에 그릴지 파악합니다. 새로운 스타일을 생성할 때, 기본 클래스의 하위 요소 위치를 재사용할 수 있습니다.
  • subControlRect()는 복합 컨트롤 내의 하위 컨트롤들에 대한 경계 사각형을 계산합니다. 새로운 스타일을 구현할 때는 기본 클래스와 다른 사각형에 대해 이 함수를 재구현해야 합니다.
  • pixelMetric()는 픽셀 메트릭, 즉 화면 픽셀 단위로 표시되는 스타일 의존적 크기를 반환합니다. 이 함수는 ` PixelMetric ` 열거형의 값을 매개변수로 받습니다. 픽셀 메트릭은 반드시 고정된 측정값일 필요는 없으며, 스타일 옵션에 따라 계산할 수도 있습니다.
  • sizeFromContents()는 주어진 콘텐츠 크기에 대한 위젯의 크기를 반환합니다. 위젯은 이를 사용하여 크기 힌트를 계산합니다.
  • hitTestComplexControl()는 복합 컨트롤 내에서 마우스 포인터가 위치한 하위 컨트롤을 반환합니다. 일반적으로 이는 subControlRect()를 사용하여 하위 컨트롤의 경계 사각형을 얻은 후, 커서 위치를 포함하는 사각형을 찾는 방식으로 처리됩니다.

QStyle 또한 polish() 및 unpolish() 함수도 제공합니다. Qt는 위젯이 처음 표시되기 전과 스타일이 변경될 때마다 위젯을 ‘폴리싱(polishing)’하고, 스타일이 변경되거나 위젯이 소멸될 때 ‘언폴리싱(unpolishing)’합니다. 이 함수들을 사용하여 위젯에 속성을 설정하거나 스타일에 필요한 기타 작업을 수행할 수 있습니다. 예를 들어, 마우스가 위젯 위에 호버 상태일 때를 파악해야 한다면, ` polish()`에서 ` WA_Hover ` 위젯 속성을 설정하십시오. 그러면 위젯은 스타일 옵션에서 ` State_MouseOver `을 설정합니다. ` polish() `의 오버로드 기능을 사용하면 스타일이 ` QApplication `을 준비하고 애플리케이션 팔레트를 조정할 수도 있습니다. 자세한 내용은 ‘팔레트’ 섹션을 참조하십시오.

마지막으로, ` QStyle `에는 일반적이면서도 까다로운 작업을 위한 정적 헬퍼 함수들이 있습니다. ` sliderPositionFromValue()` 및 ` sliderValueFromPosition()`는 슬라이더 값과 픽셀 위치 간 변환을 수행합니다. ` visualRect()`, ` visualPos()` 및 ` visualAlignment()`는 논리적 좌표와 정렬을 오른쪽에서 왼쪽으로(RTL) 레이아웃에서 대칭적인 위치로 변환하며, ` alignedRect()`는 현재 방향에 맞춰 사각형을 정렬합니다. 자세한 내용은 ` QStyle ` 클래스 문서의 ` Right-to-Left Desktops `을 참조하십시오.

QStyle 의 가상 함수를 재구현할 때는, 기본 클래스와 다른 요소만 처리하고 그 외의 모든 경우에는 기본 클래스의 구현을 호출하십시오.

팔레트

각 스타일은 QPalette 에서 제공하는 브러시 팔레트를 사용하여 그리기를 수행합니다. 각 위젯 상태마다 하나의 색상 세트( QPalette::ColorGroup)가 있습니다. 키보드 포커스가 있는 창 내의 위젯에는 '활성(active)', 다른 창의 위젯에는 '비활성(inactive)', 비활성화된 위젯에는 '비활성(disabled)' 상태가 적용됩니다. State_Active 및 State_Enabled 상태 플래그는 어떤 그룹을 사용해야 하는지 알려줍니다. 각 그룹에는 QPalette::ColorRole 에서 정의한 색상 역할이 포함되어 있습니다. 이 역할들은 위젯의 배경, 텍스트 또는 버튼을 채색하는 등 색상이 적용되는 상황을 설명합니다.

각 스타일은 색상 역할을 어떻게 사용할지 결정합니다. 예를 들어, 스타일이 그라데이션을 사용하는 경우, 팔레트 색상을 가져와 QColor::darker() 및 QColor::lighter()를 통해 더 어둡게 또는 더 밝게 조정하여 그라데이션을 생성할 수 있습니다. 일반적으로 팔레트에서 제공하지 않는 브러시가 필요한 경우, 팔레트에 포함된 브러시를 상속받아 생성하면 됩니다.

애플리케이션에 스타일을 설정하면, Qt는 스타일의 standardPalette()에서 애플리케이션 팔레트를 구축하고, 플랫폼 테마가 제공하는 역할을 재정의하도록 허용한 다음, 그 결과를 QStyle::polish()로 전달합니다. 해당 오버로드를 재구현하여 스타일에 필요한 색상을 조정하십시오. Qt는 애플리케이션이 QApplication::setPalette()를 통해 명시적으로 설정한 팔레트는 재정의하지 않습니다.

색상을 하드코딩하지 마십시오. 애플리케이션과 개별 위젯은 자체 팔레트를 설정할 수 있으며, 해당 팔레트를 사용하는 스타일은 이를 따릅니다. 또한 별도의 코드 없이도 두 팔레트에서 밝은 버전과 어두운 버전을 가져옵니다. Qt의 Fusion 스타일은 다음과 같은 방식으로 작동합니다:

밝은 색상 팔레트를 적용한 퓨전 스타일의 양식으로, 텍스트 입력란, 콤보 박스, 스핀 박스, 슬라이더, 체크박스, 진행률 표시줄 및 버튼이 포함되어 있습니다.

어두운 색상 팔레트를 적용한 퓨전 스타일의 양식으로, 텍스트 입력란, 콤보 박스, 스핀 박스, 슬라이더, 체크박스, 진행률 표시줄 및 버튼이 포함되어 있습니다.

스타일이 상상할 수 있는 모든 팔레트에서 멋지게 보일 필요는 없지만, 주어진 팔레트를 준수해야 합니다.

항목 뷰

델리게이트는 항목 뷰 내의 항목을 그립니다. Qt의 기본 델리게이트인 ` QStyledItemDelegate`는 ` CE_ItemViewItem `를 그리며, ` CT_ItemViewItem`를 통해 항목 크기를 계산하므로, 스타일은 별도의 델리게이트 없이도 항목의 모양을 제어할 수 있습니다. 스타일은 항목 뷰 헤더, 트리 분기 표시기 및 행 배경을 직접 그립니다. 새로운 데이터 유형이나 항목 데이터 역할을 지원하려면 사용자 정의 델리게이트가 필요합니다. ‘모델/뷰 프로그래밍’을 참조하십시오.

구현 관련 조언

스타일을 구현할 때는 위젯과 기본 클래스의 코드를 꼼꼼히 살펴보십시오. 위젯마다 스타일을 사용하는 방식이 다르며, 기본 클래스의 구현 방식은 그리기 상태에 영향을 미칠 수 있습니다. 예를 들어, QPainter 상태를 복원하지 않고 변경하거나, 적절한 픽셀 메트릭과 하위 요소를 사용하지 않고 일부 요소를 그리는 경우 등이 있습니다.

sizeFromContents()에서 위젯의 제안된 크기를 꼭 필요한 경우가 아니면 변경하지 마십시오. QCommonStyle 구현이 이를 처리하도록 하십시오. 변경해야 할 경우, 변경 범위를 최소화하십시오. 스타일 간에 위젯 레이아웃이 크게 다르면 애플리케이션 개발이 어려워집니다.

-reverse 명령줄 옵션이나 QGuiApplication::setLayoutDirection()을 사용하여 스타일을 테스트하여, 비대칭 요소도 오른쪽에서 왼쪽으로 진행되는 레이아웃에서 올바르게 표시되는지 확인하십시오.

QStyle, QStyleOption, QStylePainter, 위젯 스타일 참조, 체크박스 스타일 지정: 단계별 안내도참조하십시오 .

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.