이 페이지에서

위젯의 모양을 변경하는 Qt Widgets

Qt Widgets 위젯의 외관을 변경하는 세 가지 방법을 제공합니다:

  • style 는 모든 위젯을 렌더링합니다. 플랫폼 스타일을 조정하려면 QProxyStyle 를 서브클래스화하거나, 완전히 사용자 정의된 외관을 구현하려면 QCommonStyle 를 서브클래스화하십시오. 이는 Qt 자체 스타일이 사용하는 메커니즘이며, 실제 애플리케이션에서 사용해야 할 방식입니다.
  • StyleKit은 QML에서 디자인을 선언적으로 정의하고, ` QStyleKitStyle`(` QStyle `의 구현체)를 통해 위젯에 이를 적용합니다. 동일한 스타일 파일은 ` Qt Quick Controls`의 스타일도 지정합니다.
  • 스타일 시트는 CSS와 유사한 규칙을 사용하여 개별 시각적 속성을 재정의합니다. 스타일 시트는 프로토타이핑이나 소규모의 국소적인 조정을 위한 도구일 뿐, 애플리케이션의 최종 디자인을 위한 것은 아닙니다.

이 페이지에서는 각 접근 방식의 장단점과 선택 시기를 설명합니다.

접근 방식 선택

다음 표는 스타일링 목표와 이에 적합한 메커니즘을 대응시켜 보여줍니다.

목표접근 방식
기본적인 외관은 유지하되, 메트릭, 색상, 스타일 힌트 등 몇 가지 세부 사항만 변경하려는 경우QProxyStyle 의 서브클래스
예를 들어 임베디드 장치에서와 같이, 플랫폼 스타일에 구애받지 않고 애플리케이션에 고유한 외관을 부여QCommonStyle 의 서브클래스 또는 StyleKit 스타일
Qt Widgets 과 Qt Quick ControlsStyleKit 스타일
동일한 디자인의 밝은 버전과 어두운 버전을 제공합니다동일한 스타일에 대해 서로 다른 QPalette 를 사용하거나, StyleKit 테마를 적용
개발 중에 색상, 테두리, 간격을 빠르게 시험해 보거나 단일 위젯의 스타일을 변경스타일 시트

실전 애플리케이션에 스타일 적용

QStyle 의 서브클래스는 각 위젯이 스타일로 전달하는 QStyleOption 의 정보를 사용하여 QPainter 를 통해 위젯을 직접 그립니다. 스타일은 버튼의 베벨부터 트리 뷰의 가지에 이르기까지 모든 요소를 완벽하게 제어할 수 있으며, 일반적인 페인트 작업의 비용만으로 이러한 제어를 수행합니다. 즉, 일치시켜야 할 규칙도 없고, 위젯별로 재계산해야 할 상태도 없습니다.

변경하고자 하는 범위에 따라 기본 클래스를 선택하십시오:

  • QProxyStyle 다른 스타일(기본적으로 플랫폼 스타일)을 감싸며, ` drawPrimitive()`, ` pixelMetric()`, ` styleHint()`와 같은 선택된 함수를 재정의할 수 있게 해줍니다. 재정의하지 않은 모든 부분은 기본 모양과 동작을 유지합니다. 플랫폼 스타일을 조정할 때 사용하십시오.
  • QCommonStyle Qt의 모든 스타일이 공유하는 동작을 구현하며, 그리기 작업은 사용자에게 맡깁니다. 완전히 사용자 정의된 외관을 구현하기 위한 기반으로 사용하십시오. ‘스타일 및 스타일 인식 위젯’ 섹션에서는 스타일 요소를 단계별로 살펴보며 각 위젯이 어떻게 그려지는지 설명합니다.

애플리케이션이 창을 생성하기 전에 스타일을 한 번만 설정하십시오:

#include <QtWidgets>

#include "customstyle.h"

int main(int argc, char *argv[])
{
    QApplication::setStyle(new CustomStyle);
    QApplication app(argc, argv);
    QSpinBox spinBox;
    spinBox.show();
    return app.exec();
}

하드코딩된 색상 대신 스타일 옵션의 ' QPalette '에 정의된 색상으로 그리십시오. 그러면 동일한 스타일이 스타일을 전환하지 않고도 두 가지 팔레트를 사용하여 디자인의 밝은 버전과 어두운 버전을 모두 생성합니다. Qt의 Fusion 스타일이 바로 이러한 방식으로 작동합니다.

사용자가 명령줄에서 ` -style ` 옵션을 사용하여 스타일을 선택하거나, 애플리케이션 간에 스타일을 공유하려면 스타일을 플러그인으로 빌드하십시오. ` QStylePlugin ` 및 `How to Create Qt Plugins`를 참조하십시오.

StyleKit을 사용하여 QML에서 디자인 설명하기

StyleKit은 선언형 스타일링 시스템입니다. 스타일은 루트 객체가 ` Style`인 QML 파일로, 각 컨트롤 유형에 대한 색상, 크기, 반경, 테두리 및 상태에 따른 변형을 설정합니다. 속성은 컨트롤 계층 구조를 통해 전파되므로, ` abstractButton `에서 한 번 설정된 값은 모든 종류의 버튼에 적용되며, 스타일은 여러 개의 명명된 테마를 정의할 수 있습니다.

QStyleKitStyle 는 이러한 스타일을 읽어들이고 QPainter 를 사용하여 위젯을 그리는 QStyle 구현체입니다. Qt Quick 는 렌더링 과정에 관여하지 않습니다. 동일한 Style 파일은 Qt Quick Controls 의 스타일도 지정하므로, 두 툴킷을 모두 사용하는 애플리케이션은 하나의 디자인 정의만 유지하면 됩니다. 스타일에서 정의된 테마는 setThemeName()를 통해 선택됩니다.

auto *style = new QStyleKitStyle(QStringLiteral(":/styles/MyStyle.qml"));
QApplication::setStyle(style);

QStyleKitStyle 는 Qt 6.12부터 사용할 수 있습니다. StyleKit은 Qt Labs 모듈이며, Qt 릴리스 간에 API가 변경될 수 있습니다. StyleKit 위젯 예제에서는 여러 StyleKit 스타일과 테마를 사용하는 위젯 애플리케이션을 보여줍니다.

프로토타이핑을 위한 스타일 시트 사용

Qt 스타일 시트는 C++ 코드를 작성하지 않고도 CSS와 유사한 구문의 규칙을 통해 위젯의 외관을 변경합니다. 이는 디자인을 시험해 보기에 편리합니다. .qss 파일을 편집하고 애플리케이션을 다시 시작하거나, -stylesheet 명령줄 옵션을 사용하여 파일을 전달하면 Qt Widgets Designer 동일한 규칙을 미리 볼 수 있습니다. 또한 필수 입력 필드에 노란색 배경을 적용하는 등 단일 위젯을 빠르게 표시하는 데도 가장 빠른 방법입니다.

스타일 시트에는 실제 애플리케이션의 스타일링 메커니즘으로 사용하기에는 부적합한 단점이 있습니다:

  • 영향을 받는 모든 위젯은 스타일 시트 엔진을 통해 렌더링됩니다. 스타일 시트가 설정되면 QWidget::style()는 기본 style 을 감싸는 스타일 시트 스타일을 반환합니다. 각 위젯에 대해 선택자를 위젯의 클래스, 객체 이름, 속성 및 상태와 대조하고, 렌더링 규칙을 계산한 후 위젯별로 캐시합니다. 메모리 및 처리 비용은 위젯과 규칙의 수에 따라 증가합니다.
  • 스타일 시트를 변경하면 해당 스타일 시트가 적용되는 모든 요소가 다시 렌더링됩니다. QApplication::setStyleSheet()를 호출할 때마다 캐시가 지워지고 애플리케이션의 모든 위젯이 다시 렌더링되는데, 이 과정에서 글꼴, 팔레트, 기하학적 구조 및 크기 힌트가 재계산되어 눈에 띄는 깜빡임이 발생할 수 있습니다. 스타일 시트를 기반으로 테마 전환 기능을 구현하지 마십시오.
  • 부분 규칙은 기본 모양을 무시합니다. 규칙이 QPushButton 의 배경색과 같이 기본 스타일이 지원할 수 없는 요소를 요청할 경우, 스타일시트 엔진은 기본 장식을 적용하지 않은 채 요소 전체를 직접 그립니다. 이 경우 테두리, 패딩 및 모든 상태를 직접 지정해야 하며, 사소한 조정조차도 모양에 대한 완전한 설명으로 이어지게 됩니다. “스타일 시트를 사용한 Qt Widgets 사용자 정의”를 참조하십시오.
  • 선택자는 디자인을 구현 세부 사항과 연결시킵니다. 규칙은 클래스 이름, 객체 이름 및 속성 값과 일치합니다. 객체의 이름을 변경하거나 위젯 클래스를 교체하면 규칙이 더 이상 일치하지 않게 됩니다. 규칙은 스타일 없이 렌더링되는 사용자 정의 위젯에는 영향을 미치지 않습니다.
  • 스타일 시트는 프로그래밍 방식의 설정보다 우월합니다. 스타일 시트는 ` QWidget::setFont()`이나 ` QTreeWidgetItem::setBackground()`과 같은 함수로 설정된 글꼴, 팔레트, 항목 색상을 재정의하므로, 위젯의 스타일링 정보가 더 이상 한 곳에서 확인되지 않습니다.

스타일 시트와 QStyle 서브클래스를 나란히 비교한 내용은 KDAB 기사 “Say No to Qt Style Sheets”를 참조하십시오.

어쨌든 스타일 시트를 사용해야 한다면

프로토타입을 만들거나, 실제 애플리케이션에 필요한 소수의 국소적인 조정을 위한 경우, 스타일 시트를 관리하기 쉬운 수준으로 유지하십시오:

  • 규칙을 Qt 리소스 시스템에 포함된` .qss ` 파일에 보관하십시오. 첫 번째 창이 표시되기 전에 ` QApplication::setStyleSheet()`를 통해 애플리케이션에 한 번만 설정하고, 그대로 두십시오. ` QWidget::setStyleSheet()`는 특정 위젯과 그 자식 위젯에만 국한된 조정에만 사용하십시오.
  • C++ 문자열로 스타일 시트를 구성하지 마십시오. 위젯에 설정된 스타일 시트는 각 문자열마다 한 번씩이 아니라, 해당 스타일 시트가 설정된 모든 위젯에 대해 한 번씩 파싱되며, QWidget::setStyleSheet()를 호출할 때마다 문자열이 변경되지 않았더라도 위젯과 그 모든 자식 위젯이 다시 렌더링됩니다. 무효한 값에 대한 빨간색 테두리 등 데이터를 반영하기 위해 ` QString::arg()`로 생성된 문자열은 업데이트될 때마다 위젯을 다시 렌더링합니다. 대신, 하나의 스타일 시트에서 객체 이름이나 Qt 속성에 대한 선택자를 사용하여 차이를 표현하고, ‘동적 속성을 사용한 사용자 정의’에 설명된 대로 이를 재평가하십시오.
  • 색상을 하드코딩하지 마십시오. #ffffff 와 같은 리터럴 색상은 하나의 테마에만 적합합니다. palette(window), palette(text) 및 기타 팔레트 역할을 사용하여 스타일 시트가 어두운 색상 구성 등을 포함한 애플리케이션 팔레트를 따르도록 하십시오.
  • 모든 요소의 크기를 픽셀 단위로 지정하지 마십시오. px 값은 디스플레이 크기에 따라 조정되지만 사용자의 글꼴 크기에 따라 조정되지는 않습니다. 글꼴 크기에 따라 조정되어야 하는 패딩, 여백 및 크기에는 em 및 ex 길이를 사용하고, 글꼴 크기에는 pt 를 사용하십시오.

스타일 시트에서 스타일로 전환하기

프로토타입이 제품으로 전환되면 디자인을 스타일로 이전하십시오. 대부분의 스타일시트 구문에는 다음과 같은 직접적인 대응 항목이 있습니다:

스타일 시트QStyle스타일킷
색상QPalette 역할(roles), 다음에서 읽어옴: QStyleOption::palette컨트롤의 색상 속성에서 읽거나, 테마
border, padding, marginpixelMetric() 및 subElementRect()컨트롤의 테두리 및 크기 속성
:hover 및 :pressedQStyle::State 플래그와 같은 QStyleOption::statehovered 과 같은 상태 그룹 및 pressed
다음과 같은 하위 컨트롤 ::indicatordrawPrimitive() 및 drawControl()와 같은 요소의 하위 컨트롤다음과 같은 위임 속성 indicator

'스타일 및 스타일을 인식하는 위젯', ' QStyle', ' QProxyStyle', ' QCommonStyle', 'Qt Labs StyleKit' 및 'Qt 스타일 시트'도 참조하십시오 .

© 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.