스타일 및 스타일 인식 위젯

스타일( QStyle)을 상속하는 클래스는 위젯을 대신하여 그리며 GUI의 모양과 느낌을 캡슐화합니다. QStyle 클래스는 GUI의 모양과 느낌을 캡슐화하는 추상 베이스 클래스입니다. Qt의 내장 위젯은 거의 모든 그리기를 수행하기 위해 이 클래스를 사용하여 동등한 네이티브 위젯과 똑같이 보이도록 합니다.

Qt에는 다양한 스타일이 내장되어 있습니다. 특정 스타일은 특정 플랫폼에서만 사용할 수 있습니다. 사용자 정의 스타일은 플러그인으로 사용하거나 QStyleFactory::create()로 특정 스타일 클래스의 인스턴스를 생성하고 QApplication::setStyle()로 설정하여 사용할 수 있습니다.

스타일 사용자 지정하기

기존 스타일을 사용자 정의하려면 QProxyStyle 을 상속하고 원하는 가상 메서드를 다시 구현합니다. QProxyStyle 을 사용하면 특정 기본 스타일을 지정하거나 기본 스타일을 지정하지 않으면 자동으로 애플리케이션 스타일을 사용할 수 있습니다. 전자는 기본 스타일을 완전히 제어할 수 있으며 사용자 정의에서 특정 스타일 동작을 기대하는 경우에 가장 적합하지만, 후자는 기본 플랫폼 스타일로 기본 설정되는 애플리케이션 스타일을 사용자 정의할 수 있는 플랫폼에 구애받지 않는 방법을 제공합니다.

사용자 정의 스타일 구현하기

QCommonStyle 는 완전한 사용자 정의 스타일 구현을 위한 편리한 기반을 제공합니다. 접근 방식은 QProxyStyle 와 동일하지만 대신 QCommonStyle 을 상속하고 적절한 가상 메서드를 다시 구현합니다. 전체 사용자 정의 스타일을 구현하는 것은 다소 복잡하므로 이 개요를 제공합니다. 개별 Qt Widgets의 스타일을 지정하는 방법을 단계별로 설명합니다. QStyle 가상 함수, 멤버 변수, 열거형에 대해 살펴봅니다.

이 문서에서 개별 위젯의 스타일링과 관련이 없는 부분은 순차적으로 읽어야 하는데, 이는 이후 섹션이 이전 섹션에 의존하는 경향이 있기 때문입니다. 위젯에 대한 설명은 스타일을 구현하는 동안 참조용으로 사용할 수 있습니다. 그러나 경우에 따라서는 Qt 소스 코드를 참조해야 할 수도 있습니다. 이 문서를 읽고 나면 스타일 지정 과정의 순서가 명확해져서 관련 코드를 찾는 데 도움이 될 것입니다.

스타일 인식 위젯(즉, 그려지는 스타일을 따르는 위젯)을 개발하려면 현재 스타일을 사용하여 위젯을 그려야 합니다. 이 문서에서는 위젯이 어떻게 그려지는지, 스타일이 위젯에 어떤 가능성을 제공하는지 설명합니다.

위젯 스타일링용 클래스

이 클래스는 애플리케이션의 모양과 스타일을 사용자 정의하는 데 사용됩니다.

QColor

RGB, HSV 또는 CMYK 값에 기반한 색상

QColorSpace

색 공간 추상화

QColorTransform

색 공간 간 변환

QCommonStyle

GUI의 일반적인 룩앤필 캡슐화

QCursor

임의의 모양을 가진 마우스 커서

QFont

텍스트 그리기에 사용되는 글꼴에 대한 쿼리 지정

QFontDatabase

기본 창 시스템에서 사용 가능한 글꼴에 대한 정보

QFontInfo

글꼴에 대한 일반 정보

QGraphicsAnchor

QGraphicsAnchorLayout의 두 항목 사이의 앵커를 나타냅니다.

QGraphicsAnchorLayout

그래픽 보기에서 위젯을 함께 앵커링할 수 있는 레이아웃입니다.

QPalette

각 위젯 상태에 대한 색상 그룹을 포함합니다.

QStyle

GUI의 모양과 느낌을 캡슐화하는 추상 베이스 클래스

QStyleFactory

QStyle 객체 생성

QStyleHintReturn

기본 데이터 유형 이상을 반환하는 스타일 힌트

QStyleHintReturnMask

QRegion을 반환하는 스타일 힌트

QStyleHintReturnVariant

QVariant를 반환하는 스타일 힌트

QStyleOption

QStyle 함수에 사용되는 매개 변수 저장

QStylePainter

위젯 안에 QStyle 요소를 그리기 위한 편의 클래스

QStyle 구현

QStyle 의 API에는 위젯을 그리는 함수, 일반적이고 어려운 작업(예: 슬라이더 핸들의 위치 계산)을 수행하는 정적 헬퍼 함수, 그리는 동안 필요한 다양한 계산(예: 위젯의 크기 힌트 계산)을 수행하는 함수가 포함되어 있습니다. 이 스타일은 일부 위젯의 콘텐츠 레이아웃에도 도움이 됩니다. 또한 QBrush을 포함하는 QPalette 을 생성하여 그릴 수 있습니다.

QStyle 그래픽 요소를 그립니다. 요소는 위젯 또는 푸시 버튼 베벨, 창 프레임 또는 스크롤 막대와 같은 위젯 부분입니다. 이제 대부분의 draw 함수는 네 가지 인수를 받습니다:

  • 그릴 그래픽 요소를 지정하는 열거형 값
  • 해당 요소를 렌더링하는 방법과 위치를 지정하는 QStyleOption
  • 요소를 그리는 데 사용해야 하는 QPainter
  • 그리기가 수행되는 QWidget (선택 사항)

위젯이 스타일에 요소를 그리도록 요청하면 스타일은 그리기에 필요한 정보를 포함하는 클래스인 QStyleOption 를 스타일에 제공합니다. QStyleOption 덕분에 위젯에 대한 코드를 링크하지 않고도 QStyle 그리기 위젯을 만들 수 있습니다. 이렇게 하면 QStyle 의 그리기 함수를 모든 페인트 장치에서 사용할 수 있습니다. 즉, QComboBox 뿐만 아니라 모든 위젯에서 콤보박스를 그릴 수 있습니다.

위젯은 스타일에서 특수 효과(예: macOS의 애니메이션 기본 버튼)를 수행하기 위해 필요한 경우 마지막 인수로 전달되지만 필수는 아닙니다.

이 섹션에서는 스타일 요소, 스타일 옵션 및 QStyle 의 기능을 살펴봅니다. 마지막으로 팔레트가 어떻게 사용되는지 설명합니다.

항목 보기의 항목은 Qt의 델리게이트에 의해 그려집니다. 항목 뷰 헤더는 여전히 스타일에 의해 그려집니다. Qt의 기본 델리게이트인 QStyledItemDelegate 는 현재 스타일을 통해 항목을 부분적으로 그리는데, 체크 박스 표시기를 그리고 항목이 구성되는 요소의 경계 직사각형을 계산합니다. 이 문서에서는 QStyle 서브클래스를 구현하는 방법만 설명합니다. QStyledItemDelegate 에서 지원하는 데이터 유형이 아닌 다른 데이터 유형에 대한 지원을 추가하려면 사용자 정의 델리게이트를 구현해야 합니다. 델리게이트는 각 개별 위젯에 대해 프로그래밍 방식으로 설정해야 합니다(즉, 기본 델리게이트는 플러그인으로 제공할 수 없음).

스타일 요소

스타일 요소는 GUI의 그래픽 부분입니다. 위젯은 스타일 요소의 계층 구조(또는 트리)로 구성됩니다. 예를 들어 스타일이 푸시 버튼을 그리라는 요청(예: QPushButton 에서)을 받으면 레이블(텍스트 및 아이콘), 버튼 베벨 및 초점 프레임을 그립니다. 버튼 베벨은 베벨 주변의 프레임과 나중에 살펴볼 두 가지 다른 요소로 구성됩니다. 아래는 푸시 버튼 요소 트리의 개념적인 그림입니다. 개별 위젯을 살펴볼 때 QPushButton 의 실제 트리를 볼 수 있습니다.

위젯은 반드시 스타일에 하나의 요소만 그리도록 요청하여 그려지는 것은 아닙니다. 위젯은 스타일을 여러 번 호출하여 다양한 요소를 그릴 수 있습니다. 예를 들어 탭과 프레임을 개별적으로 그리는 QTabWidget 이 있습니다.

요소 유형에는 기본 요소, 제어 요소 및 복합 제어 요소의 세 가지가 있습니다. 요소는 ComplexControl, ControlElement, PrimitiveElement 열거형에 의해 정의됩니다. 각 요소 열거형의 값에는 해당 유형을 식별하는 접두사가 있습니다(복합 요소의 경우 CC_, 제어 요소의 경우 CE_, 기본 요소의 경우 PE_ ). 다음 세 섹션에서는 다양한 요소를 정의하는 요소와 이를 사용하는 위젯의 예시를 살펴보겠습니다.

QStyle 클래스 설명에는 이러한 요소의 목록과 스타일링 위젯에서의 역할이 포함되어 있습니다. 개별 위젯의 스타일을 지정할 때 이 요소들이 어떻게 사용되는지 살펴보겠습니다.

프리미티브 요소

프리미티브 요소는 여러 위젯에서 공통적으로 자주 사용되는 GUI 요소입니다. 예를 들어 회전 상자, 스크롤 막대 및 콤보 상자의 프레임, 버튼 베벨 및 화살표가 있습니다. 기본 요소는 단독으로 존재할 수 없으며 항상 더 큰 구성 요소의 일부입니다. 사용자와의 상호 작용에는 관여하지 않지만 GUI에서 수동적인 장식 역할을 합니다.

제어 요소

제어 요소는 작업을 수행하거나 사용자에게 정보를 표시합니다. 제어 요소의 예로는 테이블 및 트리 보기의 푸시 버튼, 확인란, 헤더 섹션 등이 있습니다. 제어 요소는 푸시 버튼과 같은 완전한 위젯일 필요는 없지만 탭 막대 탭 및 스크롤 막대 슬라이더와 같은 위젯 부품일 수도 있습니다. 컨트롤 요소는 수동적이지 않고 사용자와의 상호 작용에서 기능을 수행한다는 점에서 기본 요소와 다릅니다. 여러 요소로 구성된 컨트롤은 종종 스타일을 사용하여 요소의 경계 사각형을 계산합니다. 사용 가능한 하위 요소는 SubElement 열거형에 의해 정의됩니다. 이 열거형은 경계 사각형을 계산하는 데만 사용되며 하위 요소는 기본 요소, 컨트롤 및 복합 요소처럼 그릴 수 있는 그래픽 요소가 아닙니다.

복합 제어 요소

복합 컨트롤 요소에는 하위 컨트롤이 포함됩니다. 복합 컨트롤은 사용자가 마우스로 처리하는 위치와 누르는 키보드 키에 따라 다르게 작동합니다. 이는 마우스가 어떤 하위 컨트롤(있는 경우)을 가리키거나 눌렀는지에 따라 달라집니다. 복잡한 컨트롤의 예로는 스크롤 막대와 콤보 상자가 있습니다. 스크롤 막대를 사용하면 마우스를 사용하여 슬라이더를 이동하고 줄 위로 및 줄 아래로 버튼을 누를 수 있습니다. 사용 가능한 하위 컨트롤은 SubControl 열거형에 의해 정의됩니다.

스타일은 그리기 외에도 마우스를 누른 하위 컨트롤(있는 경우)에 대한 정보를 위젯에 제공해야 합니다. 예를 들어 QScrollBar 는 사용자가 슬라이더, 슬라이더 홈 또는 버튼 중 하나를 눌렀는지 알아야 합니다.

하위 컨트롤은 이전 섹션에서 설명한 컨트롤 요소와 동일하지 않다는 점에 유의하세요. 스타일을 사용하여 하위 컨트롤을 그릴 수 없으며 스타일은 하위 컨트롤이 그려져야 하는 경계 사각형만 계산합니다. 하지만 복잡한 요소는 컨트롤과 프리미티브 요소를 사용하여 하위 컨트롤을 그리는 것이 일반적이며, 이는 Qt의 내장 스타일과 Java 스타일에서도 자주 사용되는 접근 방식입니다. 예를 들어, Java 스타일은 PE_IndicatorCheckBox를 사용하여 그룹 상자( CC_GroupBox)의 하위 컨트롤인 체크 박스를 그립니다. 일부 하위 컨트롤에는 스크롤 막대 슬라이더와 같은 동등한 컨트롤 요소가 있습니다(SC_SCrollBarSliderCE_ScrollBarSlider).

기타 QStyle 작업

앞서 언급한 대로 스타일 요소와 위젯은 스타일을 사용하여 하위 요소와 하위 컨트롤의 경계 사각형을 계산합니다. 스타일에 따라 달라지는 화면 픽셀 크기인 픽셀 메트릭도 그리기 시 측정에 사용됩니다. 사용 가능한 사각형 및 픽셀 메트릭은 QStyle 에서 세 가지 열거형( SubElement, SubControl, PixelMetric)으로 표시됩니다. 열거형 값은 SE_, SC_, PM_로 시작하므로 쉽게 식별할 수 있습니다.

스타일에는 StyleHint 열거형에 값으로 표시되는 스타일 힌트 세트도 포함되어 있습니다. 모든 위젯은 동일한 기능을 가지고 있지 않으며 서로 다른 스타일로 보입니다. 예를 들어 메뉴의 메뉴 항목이 화면의 단일 열에 맞지 않는 경우 일부 스타일은 스크롤을 지원하는 반면 다른 스타일은 모든 항목을 맞추기 위해 두 개 이상의 열을 그립니다.

스타일에는 일반적으로 메시지 상자, 파일 대화 상자 등에 대한 표준 이미지(예: 경고, 질문, 오류 이미지) 집합이 있습니다. QStyle StandardPixmap 열거형을 제공합니다. 이 값은 표준 이미지를 나타냅니다. Qt의 위젯은 이를 사용하므로 사용자 정의 스타일을 구현할 때 구현 중인 스타일에서 사용하는 이미지를 제공해야 합니다.

스타일은 레이아웃에서 위젯 사이의 간격을 계산합니다. 스타일이 이러한 계산을 처리하는 방법에는 두 가지가 있습니다. PM_LayoutHorizontalSpacingPM_LayoutVerticalSpacing, Java 스타일이 수행하는 방식( QCommonStyle)을 통해 설정할 수 있습니다. 또는 레이아웃의 이 부분에 대한 더 많은 제어가 필요한 경우 QStyle::layoutSpacing() 및 QStyle::layoutSpacingImplementation()을 구현할 수 있습니다. 이러한 함수에서는 다양한 크기 정책(QSizePolicy::Policy)에 대한 제어 유형(QSizePolicy::ControlType)과 해당 위젯의 스타일 옵션에 따라 간격을 계산할 수 있습니다.

스타일 옵션

QStyleOption 의 하위 클래스에는 개별 요소의 스타일을 지정하는 데 필요한 모든 정보가 포함되어 있습니다. 스타일 옵션은 보통 스택에 인스턴스화되며 QStyle 함수의 호출자가 작성합니다. 그려지는 내용에 따라 스타일은 서로 다른 스타일 옵션 클래스를 기대합니다. 예를 들어 QStyle::PE_FrameFocusRect 요소는 QStyleOptionFocusRect 인수를 기대하며, 사용자 정의 스타일이 사용할 수 있는 사용자 정의 하위 클래스를 만들 수 있습니다. 스타일 옵션은 성능상의 이유로 공개 변수를 유지합니다.

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

특히 스타일 옵션에는 그려질 위젯의 팔레트와 경계 사각형이 포함되어 있습니다. 예를 들어 QPushButtonQCheckBox 위젯은 텍스트, 아이콘 및 아이콘 크기를 포함하는 스타일 옵션으로 QStyleOptionButton 을 사용하며, 대부분의 위젯에는 특수한 스타일 옵션이 있습니다. 모든 옵션의 정확한 내용은 개별 위젯을 살펴볼 때 설명합니다.

QStyleOption 매개 변수를 받는 QStyle 함수를 다시 구현할 때는 QStyleOption 을 하위 클래스(예: QStyleOptionFocusRect)로 형변환해야 하는 경우가 많습니다. 안전을 위해 qstyleoption_cast()를 사용하여 포인터 유형이 올바른지 확인할 수 있습니다. 객체의 유형이 올바르지 않은 경우 qstyleoption_cast()는 nullptr 을 반환합니다. 예를 들어

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

다음 코드 조각은 QStyle 을 사용하여 사용자 정의 위젯의 paintEvent()에서 포커스 사각형을 그리는 방법을 보여줍니다:

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    ...

    QStyleOptionFocusRect option(1);
    option.init(this);
    option.backgroundColor = palette().color(QPalette::Window);

    style().drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter,
                          this);
}

다음 예제는 기존 스타일에서 파생하여 그래픽 요소의 모양을 사용자 지정하는 방법을 보여줍니다:

class CustomStyle : public QProxyStyle
{
    Q_OBJECT

public:
    CustomStyle(const QWidget *widget);
    ~CustomStyle() {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                       QPainter *painter, const QWidget *widget) const override;
};

void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                QPainter *painter, const QWidget *widget) const
{
    if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
        QPolygon points(3);
        int x = option->rect.x();
        int y = option->rect.y();
        int w = option->rect.width() / 2;
        int h = option->rect.height() / 2;
        x += (option->rect.width() - w) / 2;
        y += (option->rect.height() - h) / 2;

        if (element == PE_IndicatorSpinUp) {
            points[0] = QPoint(x, y + h);
            points[1] = QPoint(x + w, y + h);
            points[2] = QPoint(x + w / 2, y);
        } else { // PE_SpinBoxDown
            points[0] = QPoint(x, y);
            points[1] = QPoint(x + w, y);
            points[2] = QPoint(x + w / 2, y + h);
        }

        if (option->state & State_Enabled) {
            painter->setPen(option->palette.mid().color());
            painter->setBrush(option->palette.buttonText());
        } else {
            painter->setPen(option->palette.buttonText().color());
            painter->setBrush(option->palette.mid());
        }
        painter->drawPolygon(points);
    } else {
        QProxyStyle::drawPrimitive(element, option, painter, widget);
    }
}

QStyle 함수

QStyle 클래스는 기본, 제어 및 복합 요소를 그리기 위한 세 가지 함수를 정의합니다: drawPrimitive(), drawControl(), drawComplexControl(). 이 함수는 다음 매개변수를 받습니다:

  • 그릴 요소의 열거형 값.
  • 요소를 그리는 데 필요한 정보가 포함된 QStyleOption.
  • 요소를 그릴 QPainter
  • QWidget 에 대한 포인터(일반적으로 요소가 그려지는 위젯).

모든 위젯이 자신에 대한 포인터를 보내는 것은 아닙니다. 함수에 전송된 스타일 옵션에 필요한 정보가 포함되어 있지 않은 경우 위젯 구현을 확인하여 자체에 대한 포인터를 보내는지 확인해야 합니다.

QStyle 클래스는 요소를 그릴 때 사용되는 도우미 함수도 제공합니다. drawItemText () 함수는 QPalette 을 매개변수로 사용하여 지정된 사각형 안에 텍스트를 그립니다. drawItemPixmap () 함수는 지정된 경계 사각형 내에 픽셀맵을 정렬하는 데 도움이 됩니다.

다른 QStyle 함수는 그리기를 수행하는 함수에 대해 다양한 계산을 수행합니다. 위젯이 여러 스타일 요소를 직접 그리는 경우 크기 힌트 및 경계 사각형을 계산하는 데도 이러한 함수를 사용합니다. 요소를 그리는 함수와 마찬가지로 도우미 함수는 일반적으로 동일한 인수를 받습니다.

  • subElementRect() 함수는 SubElement 열거형 값을 사용하여 하위 요소의 경계 사각형을 계산합니다. 스타일은 이 함수를 사용하여 요소의 다른 부분을 그릴 위치를 파악합니다. 이는 주로 재사용을 위해 수행되며 새 스타일을 만드는 경우 상위 클래스와 동일한 하위 요소의 위치를 사용할 수 있습니다.
  • subControlRect() 함수는 복잡한 컨트롤에서 하위 컨트롤의 경계 사각형을 계산하는 데 사용됩니다. 새 스타일을 구현할 때 subControlRect() 을 다시 구현하고 슈퍼 클래스와 다른 사각형을 계산합니다.
  • pixelMetric() 함수는 화면 픽셀 단위로 지정된 스타일 종속 크기인 픽셀 메트릭을 반환합니다. 이 함수는 PixelMetric 열거형 값을 받아 올바른 측정값을 반환합니다. 픽셀 메트릭은 반드시 정적 측정값일 필요는 없으며, 예를 들어 스타일 옵션을 사용하여 계산할 수 있습니다.
  • hitTestComplexControl() 함수는 복잡한 컨트롤에서 마우스 포인터가 있는 하위 컨트롤을 반환합니다. 일반적으로 subControlRect()를 사용하여 하위 컨트롤의 경계 사각형을 가져온 다음 커서의 위치를 포함하는 사각형을 확인하면 됩니다.

QStyle polish () 및 unpolish() 함수도 있습니다. 모든 위젯은 표시되기 전에는 polish() 함수로, 숨겨지면 unpolish() 함수로 전송됩니다. 이 함수를 사용하여 위젯의 속성을 설정하거나 스타일에 필요한 다른 작업을 수행할 수 있습니다. 예를 들어 마우스가 위젯 위에 언제 마우스를 가져갔는지 알아야 하는 경우 WA_Hover 위젯 속성을 설정해야 합니다. 그러면 위젯의 스타일 옵션에 State_MouseOver 상태 플래그가 설정됩니다.

QStyle 위젯에는 몇 가지 일반적이고 어려운 작업을 수행하는 몇 가지 정적 도우미 함수가 있습니다. 슬라이더 값으로부터 슬라이더 핸들의 위치를 계산하고 직사각형을 변형하고 역 레이아웃을 고려하여 텍스트를 그릴 수 있으며, 자세한 내용은 QStyle 클래스 문서를 참조하세요.

QStyle 가상 함수를 재구현하는 일반적인 방법은 슈퍼 클래스와 다른 요소에 대해 작업을 수행하는 것이며, 다른 모든 요소의 경우 슈퍼 클래스 구현을 사용하면 됩니다.

팔레트

각 스타일은 위젯을 그리는 데 사용해야 하는 색상( QBrush ) 팔레트를 제공합니다. 위젯 상태(QPalette::ColorGroup)에는 활성(키보드 포커스가 있는 창에 있는 위젯), 비활성(다른 창에 사용되는 위젯), 비활성화(비활성화된 위젯) 등 다양한 위젯 상태에 대한 색상 세트가 있습니다. 상태는 State_ActiveState_Enabled 상태 플래그를 쿼리하여 찾을 수 있습니다. 각 세트에는 QPalette::ColorRole 열거형에 지정된 특정 색상 역할이 포함되어 있습니다. 역할은 어떤 상황에서 색상을 사용해야 하는지(예: 위젯 배경, 텍스트 또는 버튼을 칠할 때) 설명합니다.

색상 역할이 사용되는 방식은 스타일에 따라 다릅니다. 예를 들어 스타일에 그라데이션을 사용하는 경우 팔레트 색상을 사용하고 QColor::darker() 및 QColor::lighter()를 사용하여 더 어둡게 또는 더 밝게 만들어 그라데이션을 만들 수 있습니다. 일반적으로 팔레트에서 제공되지 않는 브러시가 필요한 경우 팔레트에서 브러시를 파생해야 합니다.

QPalette는 팔레트를 제공하며, 다양한 위젯 상태 및 색상 역할에 대한 색상을 저장합니다. 스타일에 대한 팔레트는 standardPalette()로 반환됩니다. 애플리케이션(QApplication::setStyle()) 또는 위젯(QWidget::setStyle())에 새 스타일을 설정하면 표준 팔레트가 자동으로 설치되지 않으므로 (QApplication::setPalette()) 또는 (QWidget::setPalette())를 사용하여 팔레트를 직접 설정해야 합니다.

애플리케이션과 개별 위젯이 자체 팔레트를 설정하고 해당 스타일의 팔레트를 사용하여 그릴 수 있으므로 색상을 하드 코딩하는 것은 권장하지 않습니다. Qt의 어떤 위젯도 자체 팔레트를 설정하지 않습니다. Java 스타일은 일부 색상을 하드 코딩하지만 이는 작성자의 결정에 따른 것이므로 권장되지 않습니다. 물론 스타일이 어떤 팔레트에도 잘 어울리도록 의도된 것은 아닙니다.

구현 문제

스타일을 구현할 때 고려해야 할 몇 가지 문제가 있습니다. 여기에서는 구현에 대한 몇 가지 힌트와 조언을 제공하겠습니다.

스타일을 구현할 때는 위젯의 코드와 기본 클래스 및 그 조상 클래스의 코드를 살펴볼 필요가 있습니다. 위젯마다 스타일을 다르게 사용하기 때문에 서로 다른 스타일의 가상 함수에서 구현하면 그림의 상태에 영향을 줄 수 있기 때문입니다(예: QPainter 상태를 복원하지 않고 변경하거나 적절한 픽셀 메트릭 및 하위 요소를 사용하지 않고 일부 요소를 그리는 등).

스타일에서 QStyle::sizeFromContents() 함수로 위젯의 제안된 크기를 변경하지 말고 QCommonStyle 구현이 대신 처리하도록 하는 것이 좋습니다. 위젯의 레이아웃이 다양한 스타일에서 상당히 다르게 보이면 애플리케이션 개발이 어려울 수 있으므로 변경이 필요한 경우 크기를 작게 유지해야 합니다.

자바 스타일

저희는 Java 기본 룩앤필(이전에는 Metal이라고 알려짐)과 유사한 스타일을 구현했습니다. 구현이 비교적 간단하고 이 개요 문서에 사용할 스타일을 만들고 싶었기 때문에 이렇게 구현했습니다. 너무 광범위하지 않고 단순하게 유지하기 위해 스타일을 다소 단순화했지만, Qt는 이 스타일을 완벽하게 복사할 수 있습니다. 그러나 스타일을 Qt의 일부로 구현할 구체적인 계획은 아직 없습니다.

이 섹션에서는 몇 가지 구현 문제를 살펴보겠습니다. 마지막으로 Java 위젯의 스타일링에 대한 완전한 예제를 살펴보겠습니다. 이 문서 전체에서 예제와 위젯 이미지에 Java 스타일을 계속 사용할 것입니다. 구현 자체는 다소 복잡하므로 처음부터 끝까지 읽어야 하는 것은 아닙니다.

디자인 및 구현

스타일을 디자인하는 첫 번째 단계는 기본 클래스를 선택하는 것이었습니다. 우리는 QCommonStyle 을 서브클래스로 선택했습니다. 이 클래스는 실제 드로잉을 수행하는 것 외에는 필요한 대부분의 기능을 구현합니다.

스타일은 하나의 클래스에서 구현됩니다. 이렇게 한 이유는 모든 코드를 하나의 파일에 보관하는 것이 편리하기 때문입니다. 또한 더 적은 수의 객체를 인스턴스화하기 때문에 최적화 측면에서도 이점이 있습니다. 또한 스위치를 사용하여 함수에서 그릴 요소를 식별함으로써 함수 수를 최소한으로 유지합니다. 이로 인해 함수가 커지지만 스위치에서 각 요소에 대한 코드를 나누기 때문에 코드는 여전히 읽기 쉬워야 합니다.

Java와의 한계 및 차이점

모든 요소를 자바 스타일로 완벽하게 구현하지는 않았습니다. 이러한 방식으로 코드의 양과 복잡성을 줄였습니다. 일반적으로 이 스타일은 이 스타일 개요 문서의 실용적인 예제로서 의도된 것이지 Qt 자체의 일부가 아닙니다.

모든 위젯이 모든 상태를 구현하는 것은 아닙니다. 예를 들어 State_Disabled 와 같이 일반적인 상태도 마찬가지입니다. 그러나 각 상태는 적어도 하나의 위젯에 대해 구현됩니다.

슬라이더 아래에는 틱만 구현했습니다. 플랫 푸시 버튼도 제외되었습니다. 제목 표시줄과 도크 창 제목이 내용에 비해 너무 작아지는 경우는 처리하지 않고 서로 위에 하위 컨트롤을 그리기만 합니다.

Java 글꼴을 에뮬레이션하지 않았습니다. Java와 Qt는 매우 다른 폰트 엔진을 사용하므로 이 개요에서는 스타일을 예시로만 사용했기 때문에 그만한 가치가 있다고 생각하지 않습니다.

버튼 경사, 도구 모음 및 확인란 등에 사용되는 선형 그라데이션의 색상을 하드코딩했습니다( QPalette)는 사용하지 않았습니다. Java 팔레트에서는 이러한 색상을 생성할 수 없기 때문입니다. Java는 위젯 색상 그룹이나 역할에 따라 이러한 색상을 변경하지 않으므로(팔레트에 종속되지 않음) 어떤 경우에도 문제가 되지 않습니다.

스타일이 지정되는 것은 Qt의 위젯입니다. 일부 위젯은 Java에 전혀 존재하지 않습니다(예: QToolBox). 다른 위젯은 Java 위젯에는 없는 요소를 포함합니다. 트리 위젯은 후자의 예로, Java의 JTree에는 헤더가 없습니다.

이 스타일은 역방향 레이아웃을 처리하지 않습니다. QCommonStyle 은 역방향 위젯을 처리하며, 역방향 레이아웃을 구현한 경우 하위 요소의 위치를 변경하거나 레이블에서 텍스트 정렬을 직접 처리하는 위젯을 업데이트해야 합니다.

자바 체크박스 스타일링하기

예를 들어 Java 스타일의 체크박스 스타일링을 살펴보겠습니다. 전체 프로세스를 설명하고 관련된 모든 코드를 Java 스타일과 Qt 클래스 모두에서 인쇄합니다. 이 문서의 나머지 부분에서는 개별 위젯의 소스 코드를 살펴보지 않겠습니다. 대부분의 위젯은 체크박스와 동일한 구조를 따르므로 구체적인 구현 세부 사항을 확인해야 할 경우 코드를 검색하는 방법에 대한 아이디어를 얻을 수 있기를 바랍니다. 확인란 스타일링과 직접 관련이 없는 코드를 제거하기 위해 QCommonStyle 코드를 약간 수정했습니다.

먼저 QCheckBox 에서 체크박스용 스타일 옵션( QStyleOptionButton )을 어떻게 빌드하는지 살펴보겠습니다:

    opt.initFrom(q);
        if (down)
        opt.state |= QStyle::State_Sunken;
    if (tristate && noChange)
        opt.state |= QStyle::State_NoChange;
    else
        opt.state |= checked ? QStyle::State_On :
        QStyle::State_Off;
    if (q->testAttribute(Qt::WA_Hover) &&  q->underMouse()) {
        if (hovering)
        opt.state |= QStyle::State_MouseOver;
        else
        opt.state &= ~QStyle::State_MouseOver;
    }
    opt.text = text;
    opt.icon = icon;
    opt.iconSize = q->iconSize();

먼저 QStyleOption 에서 initFrom() 을 사용하여 모든 위젯에 공통적으로 적용되는 정보로 옵션을 설정합니다. 이에 대해서는 곧 살펴보겠습니다.

QStyleOptiondown 변수는 사용자가 상자를 누를 때 true 이며, 이는 상자의 체크 여부에 관계없이 체크박스에 해당됩니다. State_NoChange 상태는 3단계 체크박스가 있고 부분적으로 체크되어 있을 때 설정됩니다. 확인란이 선택되어 있으면 State_On, 선택되지 않은 경우 State_Off 상태가 설정됩니다. State_MouseOver 확인란 위에 마우스를 가져가고 위젯에 속성 Qt::WA_Hover 이 설정되어 있으면 QStyle::polish()에서 설정합니다. 또한 스타일 옵션에는 버튼의 텍스트, 아이콘 및 아이콘 크기도 포함됩니다.

initFrom()는 모든 위젯에 공통으로 적용되는 속성으로 스타일 옵션을 설정합니다. 여기에 그 구현을 인쇄합니다:

    state = QStyle::State_None;
    if (widget->isEnabled())
        state |= QStyle::State_Enabled;
    if (widget->hasFocus())
        state |= QStyle::State_HasFocus;
    if (widget->window()->testAttribute(Qt::WA_KeyboardFocusChange))
        state |= QStyle::State_KeyboardFocusChange;
    if (widget->underMouse())
        state |= QStyle::State_MouseOver;
    if (widget->window()->isActiveWindow())
        state |= QStyle::State_Active;
#ifdef QT_KEYPAD_NAVIGATION
    if (widget->hasEditFocus())
        state |= QStyle::State_HasEditFocus;
#endif

    direction = widget->layoutDirection();
    rect = widget->rect();
    palette = widget->palette();
    fontMetrics = widget->fontMetrics();

위젯이 활성화되면 State_Enabled 이 설정됩니다. 위젯에 포커스가 있으면 State_HasFocus 플래그가 설정됩니다. 마찬가지로 위젯이 활성 창의 자식인 경우에도 State_Active 플래그가 설정됩니다. State_MouseOver 플래그는 위젯에 WA_HoverEnabled 창 플래그가 설정되어 있는 경우에만 설정됩니다. State_HasEditFocus 을 포함하려면 Qt에서 키패드 탐색이 활성화되어 있어야 하며, 기본적으로 포함되지 않습니다.

상태 플래그 설정 외에도 QStyleOption 에는 위젯에 대한 다른 정보가 포함되어 있습니다: direction 은 레이아웃의 레이아웃 방향, rect 은 위젯의 경계 사각형(그릴 영역), palette 은 위젯을 그릴 때 사용해야 하는 QPalette, fontMetrics 은 위젯에 사용되는 글꼴의 메트릭입니다.

체크박스의 이미지와 그에 맞는 스타일 옵션을 제공합니다.

A Java style checkbox

위의 체크박스는 스타일 옵션에 다음과 같은 상태 플래그를 갖습니다:

상태 플래그Set
State_SunkenYes
State_NoChangeNo
State_On
State_Off아니요
State_MouseOver
State_Enabled
State_HasFocus
State_KeyboardFocusChange
State_Active

QCheckBox 은 스타일 옵션 optQStylePainter p 을 사용하여 QWidget::paintEvent()에 페인트합니다. QStylePainter 클래스는 스타일 요소를 그리기 위한 편의 클래스입니다. 특히 페인팅에 사용되는 QStyle 메서드를 래핑합니다. QCheckBox 는 다음과 같이 스스로를 그립니다:

    QStylePainter p(this);
    QStyleOptionButton opt = d->getStyleOption();
    p.drawControl(QStyle::CE_CheckBox, opt);

QCommonStyle CE_CheckBox 요소를 처리합니다. QCheckBox 에는 두 개의 하위 요소가 있습니다: SE_CheckBoxIndicator(체크 표시기)와 SE_CheckBoxContents(체크박스 레이블에 사용되는 내용)입니다. QCommonStyle 또한 이러한 하위 요소를 경계하는 직사각형을 구현합니다. 다음으로 QCommonStyle 코드를 살펴보겠습니다:

    QStyleOptionButton subopt = *btn;
    subopt.rect = subElementRect(SE_CheckBoxIndicator, btn, widget);
    drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget);
    subopt.rect = subElementRect(SE_CheckBoxContents, btn, widget);
    drawControl(CE_CheckBoxLabel, &subopt, p, widget);

    if (btn->state & State_HasFocus) {
        QStyleOptionFocusRect fropt;
        fropt.QStyleOption::operator=(*btn);
        fropt.rect = subElementRect(SE_CheckBoxFocusRect, btn, widget);
        drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
    }

코드 추출에서 볼 수 있듯이 공통 스타일은 CE_CheckBox의 두 하위 요소의 경계 사각형을 가져와서 그립니다. 체크박스에 포커스가 있는 경우 포커스 프레임도 그려집니다.

Java 스타일은 CE_CheckBoxIndicator를 그리고 QCommonStyle 는 CE_CheckboxLabel을 처리합니다. 각 구현을 살펴보고 CE_CheckBoxLabel부터 시작하겠습니다:

    const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt);
    uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);

    if (!styleHint(SH_UnderlineShortcut, btn, widget))
        alignment |= Qt::TextHideMnemonic;
    QPixmap pix;
    QRect textRect = btn->rect;
    if (!btn->icon.isNull()) {
        pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
        drawItemPixmap(p, btn->rect, alignment, pix);
        if (btn->direction == Qt::RightToLeft)
            textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
        else
            textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
    }
    if (!btn->text.isEmpty()){
        drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
            btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
    }

visualAlignment()은 레이아웃 방향에 따라 텍스트의 정렬을 조정합니다. 그런 다음 아이콘이 있는 경우 아이콘을 그리고 텍스트의 남은 공간을 조정합니다. drawItemText()는 정렬, 레이아웃 방향, 니모닉을 고려하여 텍스트를 그립니다. 또한 팔레트를 사용하여 텍스트를 올바른 색상으로 그립니다.

레이블을 그리는 작업은 종종 다소 복잡해집니다. 다행히도 보통은 기본 클래스에서 처리할 수 있습니다. Java 스타일은 버튼에 아이콘이 있는 경우에도 버튼 내용을 중앙에 배치하므로 자체 푸시 버튼 레이블을 구현합니다. 라벨 그리기를 다시 구현하는 예제가 필요한 경우 해당 구현을 살펴볼 수 있습니다.

이제 drawControl() 에서 CE_CheckBoxIndicator의 Java 구현을 살펴보겠습니다:

        case PE_IndicatorCheckBox: {
            painter->save();
            drawButtonBackground(option, painter, true);

            if (option->state & State_Enabled &&
                option->state & State_MouseOver &&
                !(option->state & State_Sunken)) {
                painter->setPen(option->palette.color(QPalette::Button));
                QRect rect = option->rect.adjusted(1, 1, -2, -2);
                painter->drawRect(rect);
                rect = rect.adjusted(1, 1, -1, -1);
                painter->drawRect(rect);
            }

            if (option->state & State_On) {
                QImage image(":/images/checkboxchecked.png");
                painter->drawImage(option->rect.topLeft(), image);
            }
            painter->restore();
            break;

먼저 페인터의 상태를 저장합니다. 항상 필요한 것은 아니지만, 이 경우 QCommonStyle 에는 PE_IndicatorCheckBox가 호출되었을 때와 동일한 상태의 페인터가 필요합니다(물론 함수 호출로 상태를 설정할 수도 있습니다). 그런 다음 drawButtonBackground() 을 사용하여 체크박스 표시기의 배경을 그립니다. 이것은 배경과 푸시 버튼 및 체크 박스의 프레임을 그리는 헬퍼 함수입니다. 아래에서 이 기능을 살펴보겠습니다. 그런 다음 마우스가 체크박스 위에 있는지 확인합니다. 그렇다면 상자를 누르지 않고 마우스가 그 위에 있을 때 자바 체크박스의 프레임을 그립니다. Java는 3상태 상자를 처리하지 않으므로 이를 구현하지 않았습니다.

여기서는 인디케이터에 PNG 이미지를 사용합니다. 위젯이 비활성화되어 있는지 확인할 수도 있습니다. 그런 다음 비활성화된 색상의 표시기가 있는 다른 이미지를 사용해야 합니다.

void JavaStyle::drawButtonBackground(const QStyleOption *option,
                                     QPainter *painter, bool isCheckbox) const
{
    QBrush buttonBrush = option->palette.button();
    bool sunken = option->state & State_Sunken;
    bool disabled = !(option->state & State_Enabled);
    bool on = option->state & State_On;

    if (!sunken && !disabled && (!on || isCheckbox))
        buttonBrush = gradientBrush(option->rect);

        painter->fillRect(option->rect, buttonBrush);

        QRect rect = option->rect.adjusted(0, 0, -1, -1);

        if (disabled)
            painter->setPen(option->palette.color(QPalette::Disabled,
                                                  QPalette::WindowText));
        else
            painter->setPen(option->palette.color(QPalette::Mid));

        painter->drawRect(rect);

        if (sunken && !disabled) {
            drawSunkenButtonShadow(painter, rect,
                   option->palette.color(QPalette::Mid),
                   option->direction == Qt::RightToLeft);
    }
}

위젯이 페인트 요청을 받은 시점부터 페인트가 완료될 때까지 자바 스타일로 체크박스의 스타일이 어떻게 지정되는지 살펴보았습니다. 각 위젯이 어떻게 그려지는지 자세히 알아보려면 여기에서 한 것처럼 코드를 단계별로 살펴봐야 합니다. 그러나 일반적으로 위젯이 어떤 스타일 요소를 그리는지 아는 것으로 충분합니다. 위젯은 스타일 옵션을 빌드하고 스타일을 한 번 이상 호출하여 스타일이 구성하는 스타일 요소를 그립니다. 일반적으로 위젯이 어떤 상태에 있을 수 있는지, 스타일 옵션의 다른 내용, 즉 다음 섹션에 나열된 내용을 아는 것으로도 충분합니다.

위젯 연습

이 섹션에서는 대부분의 Qt 위젯의 스타일이 어떻게 지정되는지 살펴보겠습니다. 자신만의 스타일과 위젯을 개발하는 데 시간과 노력을 절약할 수 있기를 바랍니다. 다른 곳(예: 스타일 관련 클래스의 소스 코드나 클래스 설명을 살펴봄으로써)에서 얻을 수 없는 정보는 여기서는 찾을 수 없습니다.

여기서는 주로 Java 스타일 위젯을 예로 사용합니다. Java 스타일은 요소 트리의 모든 요소를 그리지 않습니다. Java 스타일에서는 해당 위젯에 대해 표시되지 않기 때문입니다. 사용자 정의 위젯에 필요할 수 있으므로 모든 요소가 Java 스타일에 부합하는 방식으로 구현되도록 합니다(그렇다고 해서 구현을 QCommonStyle 에 맡기는 것도 배제하지는 않습니다).

각 위젯에는 다음이 제공됩니다:

  • 해당 스타일 옵션의 멤버(변수 등)가 포함된 테이블.
  • 위젯에서 설정할 수 있는 상태 플래그(QStyle::StateFlag)의 표와 상태가 설정되는 시기.
  • 해당 요소 트리( 스타일 요소 섹션 참조).
  • 요소의 윤곽이 그려진 위젯 이미지.

요소 트리에는 기본, 제어 및 복합 스타일 요소가 포함되어 있습니다. 요소 트리를 하향식으로 탐색하면 요소가 그려져야 하는 순서를 얻을 수 있습니다. 노드에는 노드의 요소를 그릴 때 고려해야 하는 하위 요소 사각형, 하위 제어 요소 및 픽셀 메트릭을 작성했습니다.

스타일링에 대한 접근 방식은 위젯의 드로잉을 중심으로 합니다. 그리는 동안 사용되는 하위 요소 직사각형, 하위 컨트롤 및 픽셀 메트릭의 계산은 요소 트리의 내용으로만 나열됩니다. 위젯에서만 사용되는 사각형과 픽셀 메트릭이 있다는 점에 유의하세요. 따라서 이러한 계산은 워크스루에서 처리되지 않습니다. 예를 들어 subControlRect() 및 sizeFromContents() 함수는 종종 subElementRect()를 호출하여 경계 직사각형을 계산합니다. 이 경우에도 나무를 그릴 수 있습니다. 그러나 이러한 계산을 수행하는 방법은 전적으로 개별 스타일에 달려 있으며, 특정 구조를 따를 필요는 없습니다(Qt는 특정 구조를 강요하지 않습니다). 하지만 여전히 적절한 픽셀 메트릭을 사용해야 합니다. 따라서 문서 크기를 제한하기 위해 트리를 포함하거나 Java(또는 다른) 스타일에 의한 계산을 설명하지 않기로 했습니다.

트리를 살펴볼 때 다양한 픽셀 메트릭, 하위 요소 사각형 및 하위 제어 사각형을 어떻게 사용해야 하는지 혼란스러울 수 있습니다. QStyle 열거형 설명을 읽은 후 확실하지 않은 경우 QCommonStyle 구현을 살펴보는 것이 좋습니다.

위젯 이미지에서 설명하는 경계 사각형 중 일부는 동일합니다. 그 이유는 일부 요소는 배경을 그리고 다른 요소는 프레임과 레이블을 그리기 때문입니다. 확실하지 않은 경우 QStyle 에서 각 요소에 대한 설명을 확인하세요. 또한 일부 요소는 레이아웃, 즉 다른 요소를 그릴 위치를 결정하기 위해 존재합니다.

공통 위젯 속성

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

공통 상태가 표시된 표는 다음과 같습니다:

상태상태 설정 시기
State_Enabled위젯이 비활성화되지 않은 경우 설정됩니다( QWidget::setEnabled() 참조).
State_Focus위젯에 포커스가 있는 경우 설정됩니다( QWidget::hasFocus() 참조).
State_KeyboardFocusChange사용자가 키보드로 포커스를 변경할 때 설정됩니다( Qt::WA_KeyboardFocusChange 참조 ).
State_MouseOver마우스 커서가 위젯 위에 있을 때 설정합니다.
State_Active위젯이 활성 창의 자식인 경우 설정합니다.
State_HasEditFocus위젯에 편집 포커스가 있는 경우 설정

위젯의 다른 일반적인 멤버는 다음과 같습니다:

멤버Content
rect그릴 요소의 경계 사각형입니다. 이것은 위젯 경계 사각형(QWidget::rect())으로 설정됩니다.
direction레이아웃 방향, Qt::LayoutDirection 열거형 값입니다.
팔레트요소를 그릴 때 사용할 QPalette. 위젯 팔레트(QWidget::palette())로 설정됩니다.
폰트 메트릭스위젯에 텍스트를 그릴 때 사용할 QFontMetrics.

복합 스타일 요소에 사용되는 복합 스타일 옵션( QStyleOptionComplex)을 상속하는 클래스는 subControlsactiveSubControls 두 변수를 공유합니다. 두 변수 모두 QStyle::SubControl 열거형 값의 OR 조합입니다. 복합 컨트롤이 어떤 하위 컨트롤로 구성되어 있으며 현재 활성화되어 있는 컨트롤을 나타냅니다.

앞서 언급했듯이 스타일은 위젯 콘텐츠의 크기를 계산하며, 위젯은 이를 바탕으로 크기 힌트를 계산합니다. 또한 복합 컨트롤은 스타일을 사용하여 마우스가 어느 하위 컨트롤 위에 있는지 테스트합니다.

위젯 참조

더 이상 지체하지 않고 각 위젯마다 고유한 하위 섹션이 있는 위젯 안내를 소개합니다.

푸시 버튼

푸시 버튼의 스타일 구조는 아래와 같습니다. 트리를 하향식으로 탐색하면 요소가 그려져야 하는 순서를 알 수 있습니다.

The style structure for push buttons

요소 바운드와 관련된 버튼의 레이아웃은 스타일마다 다릅니다. 따라서 이에 대한 개념적인 이미지를 표시하기가 어렵습니다. 또한 요소는 동일한 바운드를 가질 수 있으며, 심지어 의도된 바운드일 수도 있습니다. 예를 들어 PE_PushButtonBevelQCommonStyle 에서 포함된 요소를 그리는 데 사용됩니다: PE_FrameDefaultButton, PE_FrameButtonBevel, PE_PanelButtonCommand, 모두 공통된 스타일로 동일한 바운드를 갖습니다. PE_PushButtonBevel 는 메뉴 표시기를 그리는 역할도 담당합니다(QCommonStylePE_IndicatorArrowDown 를 그립니다).

요소의 경계 사각형을 보여주는 자바 스타일의 푸시 버튼 이미지가 아래에 나와 있습니다. 색상은 이미지에서 경계 사각형을 구분하는 데 사용되며 다른 용도로 채워지지 않습니다. 이는 다른 위젯의 유사한 이미지에도 적용됩니다.

Java 스타일은 물론 Qt로 구현된 다른 모든 스타일은 PE_FrameButtonBevel 을 사용하지 않습니다. PE_DefaultFrame 버튼은 PE_PanelButtonCommand 의 직사각형을 PM_ButtonDefaultIndicator 으로 조정하는 것이 일반적입니다. CE_PushButtonLabelPM_DefaultFrameWidth 으로 직사각형을 조정하여 찾습니다.

이제 푸시 버튼의 스타일 옵션인 QStyleOptionButton 을 살펴 보겠습니다. 다음은 스타일 옵션에서 QPushButton 설정할 수 있는 상태에 대한 표입니다:

상태상태 설정 대상
State_Sunken버튼이 아래로 내려가거나 메뉴가 눌려 있음
State_On버튼이 선택됨
State_Raised버튼이 평평하지 않고 눌리지 않은 상태

QStyleOptionButton 의 다른 멤버는 다음과 같습니다:

회원콘텐츠
기능다양한 버튼 속성을 설명하는 QStyleOptionButton::ButtonFeatures 열거형의 플래그(열거형 참조)
아이콘QIcon 버튼(있는 경우)
iconSize아이콘의 QSize
text버튼 텍스트의 QString

체크 및 라디오 버튼

라디오 버튼과 체크 버튼의 구조는 동일합니다. QCheckBox 요소와 픽셀 메트릭 이름을 사용하여 구조를 표시합니다:

QStyleOptionButton 은 체크 버튼과 라디오 버튼 모두의 스타일 옵션으로 사용됩니다. 먼저 옵션에서 설정할 수 있는 상태 표를 제공합니다:

상태상태 설정 시기
State_sunken상자를 눌렀을 때
State_NoChange상자가 부분적으로 선택되어 있습니다(3상태 체크박스의 경우).
State_On상자가 선택된 경우
State_Off상자가 선택 취소된 경우

QStyleOptionButton 클래스의 다른 멤버에 대한 표는 푸시 버튼을 참조하세요.

Qt에서 QTabBar 는 스타일을 사용하여 탭을 그립니다. 탭은 QTabBar 을 포함하는 QTabWidget 또는 별도의 막대로 존재합니다. 바가 탭 위젯의 일부가 아닌 경우, 자체적인 베이스를 그립니다.

QTabBar 는 탭을 배치하므로 스타일은 탭 배치를 제어할 수 없습니다. 그러나 탭을 배치하는 동안 바는 스타일에 PM_TabBarTabHSpacePM_TabBarTabVSpace, 즉 탭 표시줄 탭 레이블(아이콘 및 텍스트)의 최소 크기보다 너비와 높이가 더 큰 것을 요청합니다. 또한 탭 바에서 CT_TabBarTab 을 요청하는 것처럼 스타일은 탭이 배치되기 전에 탭 크기에 영향을 줄 수도 있습니다. 바의 경계 사각형은 위젯의 일부인 경우 탭 위젯에 의해 결정됩니다(아직 CT_TabBarTab)를 고려 중입니다.

탭 바는 모든 탭이 맞지 않을 때 탭 바에 표시되는 버튼을 그리는 역할을 합니다. 버튼의 배치는 스타일에 의해 제어되지 않지만 버튼은 QToolButtons이므로 스타일에 의해 그려집니다.

다음은 QTabWidgetQTabBar 의 스타일 구조입니다:

점선은 QTabWidget 에 탭 바가 포함되어 있지만 탭 바 자체를 그리지 않음을 나타냅니다. QTabBar 은 탭 위젯의 일부가 아닐 때만 기준선을 그리고 모든 탭이 맞지 않을 때 바를 스크롤하는 두 개의 도구 버튼(해당 요소 트리는 도구 버튼 참조)을 유지합니다. 또한 버튼은 탭 막대의 자식이기 때문에 막대 뒤에 그려집니다. 탭의 경계 사각형은 PM_TabBarBaseOverlap 까지 겹칩니다.

다음은 Java 스타일의 탭 위젯입니다:

Java 스타일에서 탭 막대 모양과 레이블은 CE_TabBarTab 과 동일한 경계 직사각형을 갖습니다. 탭이 탭 위젯 프레임과 겹치는 것을 확인할 수 있습니다. 탭 표시줄의 밑면(그려진 경우)은 탭과 프레임이 겹치는 영역입니다.

탭의 스타일 옵션(QStyleOptionTab)에는 탭을 그리는 데 필요한 정보가 포함되어 있습니다. 이 옵션에는 탭 표시줄에서 탭의 위치, 선택한 탭의 위치, 탭의 모양, 텍스트, 아이콘 및 아이콘의 크기가 포함됩니다.

Java 스타일의 탭은 겹치지 않으므로 일반적인 스타일의 탭 위젯 이미지도 표시됩니다. 탭을 가로로 겹치게 하려면 CE_TabBarTabShape 에서 탭을 그릴 때 그렇게 하면 되며, 사각형으로 둘러싸인 탭은 탭 막대에 의해 변경되지 않습니다. 탭은 왼쪽에서 오른쪽으로 북쪽 탭 막대 모양, 위에서 아래로 동쪽 탭 막대 모양 등으로 그려집니다. 선택한 탭은 가장 마지막에 그려지므로 다른 탭 위에 쉽게 그릴 수 있습니다(더 크게 그릴 경우).

탭 바에서 탭에 설정할 수 있는 상태 표는 다음과 같습니다:

상태상태 설정 시기
State_Sunken마우스로 탭을 누릅니다.
State_Selected현재 탭인 경우.
State_HasFocus탭 막대에 초점이 있고 탭이 선택되어 있습니다.

탭 표시줄이 활성화되어 있지 않더라도 개별 탭은 비활성화될 수 있습니다. 탭 표시줄이 활성화되어 있으면 탭이 활성화됩니다.

다음은 QStyleOptionTab 의 멤버 표입니다:

회원콘텐츠
코너 위젯탭 표시줄에 코너 위젯이 있는지 여부와 어떤 코너 위젯이 있는지를 나타내는 CornerWidget 열거형 열거형의 플래그입니다.
icon탭의 QIcon.
iconSize아이콘의 QSize 크기입니다.
위치다른 탭을 기준으로 바에서 탭의 위치를 나타내는 TabPosition 열거형 값입니다.
row탭이 어느 행에 있는지 보관합니다.
선택된 위치선택한 탭이 탭에 인접했는지 또는 탭인지를 나타내는 SelectedPosition 열거형 열거형 값입니다.
모양탭의 모서리가 둥근지 삼각형인지 여부와 탭의 방향을 나타내는 QTabBar::Shape 열거형 값입니다.
text탭 텍스트입니다.

탭 위젯의 프레임은 QStyleOptionTabWidgetFrame 을 스타일 옵션으로 사용합니다. 여기에 그 멤버를 나열합니다. 공통 플래그 외에 다른 상태는 설정되어 있지 않습니다.

멤버content
왼쪽 모서리 위젯 크기왼쪽 모서리 위젯의 QSize (있는 경우)입니다.
오른쪽 모서리 위젯 크기오른쪽 모서리 위젯(있는 경우)의 QSize.
lineWidth패널을 그리기 위한 선의 너비입니다.
midLineWith이 값은 현재 항상 0입니다.
모양탭 표시줄의 탭 모양입니다.
탭바 크기탭 표시줄의 QSize 크기입니다.

스크롤 막대

스크롤바의 스타일 구조는 다음과 같습니다:

QScrollBar 스타일 옵션을 생성한 다음 CC_ScrollBar 을 그립니다. 일부 스타일은 PE_PanelButtonBevel 으로 추가 페이지 및 하위 페이지의 배경을 그리고 표시기 화살표를 사용하여 다음 줄 및 이전 줄 표시기에 화살표를 그리기도 하지만 개별 스타일에 따라 사용법이 달라지므로 트리에 포함시키지 않았습니다. 스타일의 PM_MaximumDragDistance 은 마우스가 스크롤 막대의 경계에서 핸들을 움직이면서 이동할 수 있는 최대 거리(픽셀)입니다.

다음은 자바 스타일의 스크롤바 이미지입니다:

스크롤바에 두 줄 표시기가 있어 자바 스타일과 약간 다르다는 것을 알 수 있습니다. 이는 하나의 하위 컨트롤에 대해 두 개의 개별 경계 사각형을 가질 수 있다는 것을 보여주기 위해 이렇게 했습니다. 스크롤 막대는 전적으로 자바 스타일로 구현된 위젯의 예시입니다. QCommonStyle 는 그림에 포함되지 않습니다.

스크롤 막대가 스타일 옵션에서 설정할 수 있는 여러 가지 상태를 살펴보겠습니다:

상태상태 설정 시기
State_Horizontal스크롤 막대가 가로입니다.

QScrollBar 의 스타일 옵션은 QStyleOptionSlider 입니다. 그 멤버는 다음 표에 나열되어 있습니다. 이 옵션은 모든 QAbstractSlider에서 사용되며 여기서는 스크롤 막대와 관련된 멤버만 설명합니다.

멤버내용
최대스크롤 막대의 최대값입니다.
최소스크롤 막대의 최소값입니다.
노치 타겟노치 사이의 픽셀 수입니다.
방향스크롤 막대가 세로인지 가로인지를 지정하는 Qt::Orientation 열거형 값입니다.
페이지 단계페이지 단계에서 슬라이더의 값을 늘리거나 줄일 숫자(슬라이더의 크기 및 값 범위 기준)입니다.
단일 스텝단일(또는 라인) 단계에서 슬라이더의 값을 늘리거나 줄일 수 있는 숫자입니다.
슬라이더 값슬라이더의 값입니다.
슬라이더 위치슬라이더 핸들의 위치입니다. 스크롤 막대가 QAbstractSlider::tracking 인 경우 sliderValue 과 동일합니다. 그렇지 않은 경우 마우스가 핸들에서 손을 떼기 전에 스크롤 막대의 값이 업데이트되지 않습니다.
upsideDown스크롤 막대가 값을 증가시키는 방향을 유지합니다. 모든 추상 슬라이더에 QStyleOption::direction 대신 사용됩니다.

슬라이더

슬라이더의 크기 힌트를 계산할 때 스타일에서 PM_SliderThicknessPM_SliderLength 을 쿼리합니다. 스크롤 막대와 마찬가지로 QSlider 는 마우스가 슬라이더 범위에서 PM_MaximumDragDistance 내에 있는 경우에만 사용자가 핸들을 움직일 수 있도록 합니다. 자체적으로 그릴 때 스타일 옵션을 생성하고 CC_Slider 으로 drawComplexControl() 을 호출합니다:

또한 자바 스타일로 슬라이더의 그림을 표시합니다. 모든 그리기가 CC_Slider 에서 이루어지므로 하위 요소의 경계 직사각형을 표시합니다.

QSlider 모든 QAbstractSlider에서와 같이 QStyleOptionSlider 을 사용합니다. QSlider 에 영향을 미치는 멤버가 있는 표를 표시합니다:

멤버내용
최대슬라이더의 최대값입니다.
minimum슬라이더의 최소값입니다.
노치 타겟각 노치 사이의 픽셀 수입니다.
orientation슬라이더가 세로인지 가로인지를 나타내는 Qt::Orientation 열거형 값입니다.
페이지 단계페이지 단계에서 슬라이더의 값을 늘리거나 줄일 수 있는 숫자입니다.
단일 스텝단일(또는 라인) 단계에서 슬라이더의 값을 늘리거나 줄일 수 있는 숫자입니다.
슬라이더 값슬라이더의 값입니다.
슬라이더 위치슬라이더 값으로 지정된 슬라이더의 위치입니다. 슬라이더가 tracking 인 경우 sliderValue 과 같으며, 그렇지 않은 경우 마우스로 핸들을 놓을 때까지 슬라이더의 값은 변경되지 않습니다.
upsideDown이 멤버는 모든 추상 슬라이더에 QStyleOption::direction 대신 사용됩니다.

슬라이더는 역방향 레이아웃에 방향을 사용하지 않고 upsideDown 을 사용한다는 점에 유의해야 합니다.

스핀 박스

QSpinBox 을 그리면 QStyleOptionSpinBox 을 생성하고 스타일에 CC_SpinBox 을 그리도록 요청합니다. 편집 필드는 스핀 박스의 자식인 라인 편집입니다. 필드의 치수는 SC_SpinBoxEditField 를 사용하여 스타일에 의해 계산됩니다.

다음은 스핀 박스의 스타일 트리입니다. 스타일이 버튼 패널 프리미티브를 사용하여 표시기 배경을 칠할 필요는 없습니다. 트리 아래에서 하위 요소를 보여주는 이미지를 볼 수 있습니다. QSpinBox 자바 스타일로.

QStyleOptionSpinBox 은 회전 상자에 대한 스타일 옵션입니다. 스핀 박스에 다음과 같은 상태를 설정할 수 있습니다:

상태상태 설정 시기
State_Sunken하위 컨트롤 CC_SpinUp 또는 CC_SpinDown 중 하나를 마우스로 누르면 설정됩니다.

스핀 박스 스타일 옵션의 나머지 멤버는 다음과 같습니다:

속성함수
frame회전 상자가 프레임을 그리는 경우 true 부울입니다.
buttonSymbols위/아래 버튼의 기호를 결정하는 ButtonSymbols 열거형 값입니다.
stepEnabled회전 상자 버튼 중 어느 버튼을 눌렀는지를 나타내는 StepEnabled 열거형 값입니다.

제목 표시줄

제목 표시줄 복합 컨트롤인 CC_TitleBarQMdiArea 에서 내부 창의 제목 표시줄을 그리는 데 사용됩니다. 일반적으로 창 제목과 닫기, 최소화, 시스템 메뉴 및 최대화 버튼으로 구성됩니다. 일부 스타일은 창을 음영 처리하는 버튼과 상황에 맞는 도움말을 위한 버튼도 제공합니다.

바는 하위 요소를 사용하지 않고 CC_TitleBar 에 그려집니다. 개별 스타일에서 버튼을 그리는 방식은 스타일에 따라 다르지만 스타일에서 제공해야 하는 버튼에 대한 표준 픽스맵이 있습니다.

Java 스타일의 제목 표시줄 위에 있는 이미지에는 Java 스타일에서 지원하는 하위 요소의 경계 사각형이 표시됩니다(모두 표준 픽셀맵으로 그려짐). 버튼 배경은 PE_PanelButtonTool 을 사용하여 그리는 것이 일반적이지만 필수는 아닙니다.

제목 표시줄의 스타일 옵션은 QStyleOptionTitleBar 이며 그 멤버는 다음과 같습니다:

Member콘텐츠
아이콘제목 표시줄의 아이콘입니다.
텍스트제목 표시줄의 레이블 텍스트입니다.
창 플래그Qt::WindowFlag 열거형의 플래그. QMdiArea 에서 창 관리를 위해 사용하는 창 플래그입니다.
titleBarState제목 표시줄이 포함된 창의 QWidget::windowState()입니다.

콤보 상자

QComboBoxCC_ComboBoxCE_ComboBoxLabel 를 사용하여 편집할 수 없는 상자의 버튼과 레이블을 그리는 스타일을 사용합니다.

사용자가 콤보 상자를 클릭하면 표시되는 목록은 델리게이트에 의해 그려지는데, 이 개요에서는 다루지 않습니다. 그러나 스타일을 사용하여 하위 요소 SC_ComboBoxListBoxPopup 를 사용하여 목록의 크기와 위치를 제어할 수 있습니다. 스타일은 또한 편집 가능한 상자의 편집 필드( SC_ComboBoxEditField; 필드 자체는 콤보 상자의 자식인 QLineEdit )의 위치를 결정합니다.

하위 요소와 하위 요소 직사각형의 윤곽을 그린 Java 스타일 콤보 상자 위에 이미지를 표시합니다:

Java 콤보 상자는 포커스 직사각형을 사용하지 않으며, 포커스가 있으면 배경색이 변경됩니다. SC_ComboBoxEdit 필드는 편집 필드의 크기를 계산하는 데 QComboBox 및 콤보 상자 레이블의 크기를 계산하는 스타일에 모두 사용됩니다.

콤보 상자의 스타일 옵션은 QStyleOptionComboBox 이며 다음과 같은 상태를 설정할 수 있습니다:

상태언제 설정
State_Selected상자는 편집할 수 없으며 초점이 있습니다.
State_SunkenSC_ComboBoxArrow 활성 상태입니다.
State_on상자의 컨테이너(목록)가 표시됩니다.

다른 멤버의 스타일 옵션이 표시됩니다:

멤버콘텐츠
현재 아이콘콤보 상자의 현재(선택된) 항목의 아이콘입니다.
현재 텍스트상자에 있는 현재 항목의 텍스트입니다.
편집 가능콤보 상자가 편집 가능한지 여부를 유지합니다.
프레임콤보 상자에 프레임이 있는지 여부를 유지합니다.
iconSize현재 항목 아이콘의 크기입니다.
팝업 사각형콤보 상자 팝업 목록의 경계 사각형입니다.

그룹 상자

크기 힌트를 계산할 때 QGroupBox 는 스타일에서 세 가지 픽셀 메트릭을 가져옵니다: PM_IndicatorWidth, PM_CheckBoxLabelSpacing, PM_IndicatorHeight. QGroupBox 에는 다음과 같은 스타일 요소 트리가 있습니다:

Qt는 체크 박스를 그리는 방식에 제한을 두지 않습니다; Java 스타일은 CE_IndicatorCheckBox 로 체크 박스를 그립니다. 전체 트리는 체크 및 라디오 버튼을 참조하십시오.

또한 하위 컨트롤과 하위 컨트롤 사각형이 그려진 위젯의 이미지도 제공합니다:

그룹 상자의 스타일 옵션은 QStyleOptionGroupBox 입니다. 다음과 같은 상태를 설정할 수 있습니다:

상태언제 설정
State_On확인란이 선택되어 있습니다.
State_Sunken확인란이 눌려 있습니다.
State_Off확인란이 선택 취소되어 있거나 확인란이 없는 경우.

QStyleOptionGroupBox 의 나머지 멤버는 다음과 같습니다:

회원콘텐츠
기능그룹 상자의 프레임을 설명하는 QStyleOptionFrame::FrameFeatures 열거형 열거형의 플래그입니다.
lineWidth패널을 그릴 선 너비입니다. 이 값은 항상 1입니다.
text그룹 상자의 텍스트입니다.
textAlignment그룹 상자 제목의 맞춤입니다.
textColor텍스트의 QColor 색상입니다.

스플리터

분할기의 구조는 단순하고 하위 요소를 포함하지 않으므로 분할기 이미지를 포함하지 않습니다. CE_Splitter 은 다른 요소나 메트릭을 사용하지 않습니다.

스타일 옵션의 경우, 스플리터는 기본 클래스 QStyleOption 를 사용합니다. 다음과 같은 상태 플래그를 설정할 수 있습니다:

State언제 설정
State_Horizontal가로 분할기인 경우 설정합니다.

QSplitterinitFrom()를 사용하여 옵션을 설정하지 않고 State_MouseOverState_Disabled 플래그를 직접 설정합니다.

진행률 표시줄

CE_ProgressBar 요소는 QProgressBar 에서 사용되며 이 위젯에서 사용하는 유일한 요소입니다. 스타일 구조부터 시작하겠습니다:

다음은 일반적인 스타일의 진행률 표시줄입니다(자바 스타일의 경계 사각형은 동일합니다):

QProgressBar 의 스타일 옵션은 QStyleOptionProgressBar 입니다. 이 바에는 상태 플래그가 설정되어 있지 않지만 옵션의 다른 멤버는 설정되어 있습니다:

MemberContent
minimum막대의 최소값입니다.
최대막대의 최대값입니다.
진행률막대의 현재 값입니다.
textAlignment레이블에서 텍스트가 정렬되는 방식입니다.
textVisible레이블이 그려지는지 여부입니다.
text레이블 텍스트입니다.
방향진행률 표시줄은 세로 또는 가로일 수 있습니다.
반전된 모양진행률이 반전되어 표시됩니다(즉, 가로 막대에서 오른쪽에서 왼쪽으로).
bottomToTop부울, true, 세로 진행률 표시줄의 레이블을 90도 회전합니다.

도구 버튼

도구 버튼은 독립적으로 또는 도구 모음의 일부로 존재합니다. 어느 쪽이든 동일하게 그려집니다. QToolButton 은 하나의 스타일 요소인 CC_ToolButton 만 그립니다.

아래는 위젯의 스타일 구조 트리입니다:

PE_FrameButtonToolPE_IndicatorArrowDown 은 Java 스타일이 그리는 대로 트리에 포함되지만 원하는 경우 생략해도 됩니다. 구조가 다를 수도 있습니다. QCommonStyle 예를 들어 CE_ToolButton 에서 PE_IndicatorButtonDropDownPE_IndicatorArrowDown 을 모두 그립니다.

또한 사각형과 하위 컨트롤을 경계로 하는 하위 요소의 윤곽을 그린 도구 버튼 이미지가 있습니다.

다음은 도구 버튼의 상태 표입니다:

상태설정 시기
State_AutoRise도구 버튼에 자동 상승 속성이 설정되어 있습니다.
State_Raised버튼이 가라앉지 않았습니다(즉, 마우스로 확인하거나 눌러서).
State_Sunken버튼이 내려져 있습니다.
State_On버튼이 선택되어 있고 체크되어 있습니다.

QStyleOptionToolButton 또한 다음과 같은 멤버를 포함합니다:

멤버콘텐츠
arrowType버튼 화살표의 방향을 포함하는 Qt::ArrowType 열거형 값입니다(아이콘 대신 화살표를 사용할 경우).
기능버튼에 화살표가 있는지, 메뉴가 있는지, 팝업 지연이 있는지를 설명하는 QStyleOptionToolButton::ButtonFeature 열거형의 플래그입니다.
font버튼 레이블의 QFont.
icon도구 버튼의 QIcon.
iconSize버튼 아이콘의 아이콘 크기입니다.
posQWidget::pos()에 지정된 버튼의 위치입니다.
text버튼의 텍스트입니다.
toolButtonStyle버튼에 아이콘을 표시할지, 텍스트를 표시할지 또는 둘 다 표시할지를 결정하는 Qt::ToolButtonStyle 열거형 값입니다.

툴바

툴바는 main window framework 의 일부이며, 스타일 옵션을 빌드하는 동안 해당 툴바가 속한 QMainWindow 과 협력합니다. 기본 창에는 툴바를 배치할 수 있는 4개의 영역이 있습니다. 도구 모음은 창의 네 면(즉, 북쪽, 남쪽, 동쪽, 서쪽) 옆에 배치됩니다. 각 영역 내에는 도구 모음이 두 줄 이상 있을 수 있으며, 한 줄은 동일한 방향(세로 또는 가로)의 도구 모음이 나란히 배치된 것으로 구성됩니다.

Toolbars Qt에서 도구 모음은 세 가지 요소로 구성됩니다: CE_ToolBar, PE_IndicatorToolBarHandle, 그리고 PE_IndicatorToolBarSeparator. 경계 사각형(즉, 도구 모음과 그 내용의 위치 및 크기)을 계산하는 것은 QMainWindowLayout입니다. 기본 창은 또한 도구 모음의 크기를 계산할 때 도구 모음에 있는 항목의 sizeHint() 을 사용합니다.

다음은 QToolBar 의 요소 트리입니다:

점선은 QToolBar 이 QToolBarLayout의 인스턴스를 유지하며 QToolBarSeparators는 QToolBarLayout이 유지한다는 것을 나타냅니다. 툴바가 플로팅된 경우(즉, 자체 창이 있는 경우) PE_FrameMenu 요소가 그려지고, 그렇지 않으면 QToolBarCE_ToolBar 을 그립니다.

다음은 자바 스타일의 툴바 이미지입니다:

QToolBarSaparator는 스타일 옵션으로 QStyleOption 을 사용합니다. 툴바가 가로로 표시되는 경우 State_Horizontal 플래그를 설정합니다. 그 외에는 initFrom()를 사용합니다.

QToolBar 의 스타일 옵션은 QStyleOptionToolBar 입니다. 공통 플래그 외에 설정되는 유일한 상태 플래그는 바가 수평인 경우(즉, 북쪽 또는 남쪽 툴바 영역에 있는 경우) State_Horizontal 입니다. 스타일 옵션의 멤버 변수는 다음과 같습니다:

MemberContent
특징막대를 움직일 수 있는지 여부는 이동 가능 또는 없음인 ToolBarFeature 값에 저장됩니다.
선 너비도구 모음 프레임의 너비입니다.
midLineWidth이 변수는 현재 사용되지 않으며 항상 0입니다.
line 위치툴바가 속한 툴바 영역 내 툴바 선의 위치입니다.
위치 내 선툴바 라인 내 툴바의 위치입니다.
toolBarArea툴바가 위치한 툴바 영역입니다.

Qt의 메뉴는 QMenu 에서 구현됩니다. QMenu 은 액션 목록을 유지하며, 이를 메뉴 항목으로 그립니다. QMenu 은 페인트 이벤트를 받으면 각 메뉴 항목의 크기를 계산하고 CE_MenuItem 을 사용하여 개별적으로 그립니다. 메뉴 항목에는 레이블(내용)에 대한 별도의 요소가 없으므로 모든 그리기는 CE_MenuItem 에서 이루어집니다. 메뉴는 또한 PE_FrameMenu 를 사용하여 메뉴의 프레임을 그립니다. 스타일이 스크롤을 지원하는 경우 CE_MenuScroller 도 그립니다. 메뉴가 경계 사각형에 비해 너무 크면 CE_MenuTearOff 이 그려집니다.

스타일 구조 트리에는 스타일링 관련 작업도 수행하므로 QMenu 도 포함됩니다. 메뉴 항목의 경계 사각형은 메뉴의 크기 힌트 및 메뉴가 표시되거나 크기가 조정될 때 계산됩니다.

CE_MenuScrollerCE_MenuTearOff 요소는 QCommonStyle 에서 처리하며 메뉴가 너무 커서 화면에 맞지 않는 한 표시되지 않습니다. PE_FrameMenu 는 팝업 메뉴에만 그려집니다.

QMenu 는 동작에 따라 직사각형을 계산하고 스타일이 이를 지원하는 경우 CE_MenuItemCE_MenuScroller 을 호출합니다.

PE_IndicatorCheckBox 체크 가능한 메뉴 항목을 그릴 때는 PE_IndicatorMenuCheckMark)와 PE_IndicatorRadioButton 를 사용하는 것이 일반적이지만, 이는 선택 사항이며 스타일마다 다르므로 스타일 트리에 포함하지 않았습니다.

메뉴 항목의 스타일 옵션은 QStyleOptionMenuItem 입니다. 다음 표에서는 상태 플래그 및 기타 멤버에 대해 설명합니다.

상태설정 시기
State_Selected마우스가 동작 위에 있고 동작이 구분 기호가 아닌 경우.
State_Sunken마우스가 메뉴 항목을 누르고 있습니다.
State_DownArrow메뉴 항목이 메뉴 스크롤러이고 메뉴가 아래로 스크롤되는 경우 설정됩니다.
멤버콘텐츠
체크 유형체크할 수 없음, 독점, 비독점 중 하나인 CheckType 열거형 값입니다.
checked메뉴 항목이 체크된 경우 true 부울입니다.
font메뉴 항목의 텍스트에 사용할 QFont.
아이콘메뉴 항목의 QIcon.
최대 아이콘 너비아이콘에 허용되는 최대 너비입니다.
menuHasCheckableItems메뉴에서 하나 이상의 항목이 체크 가능한 경우 true 부울입니다.
menuItemType메뉴 항목의 유형입니다. MenuItemType 의 값입니다.
menuRect메뉴 항목이 있는 QMenu 의 경계 사각형입니다.
tabWidth메뉴 항목의 텍스트와 바로 가기 사이의 거리입니다.
text메뉴 항목의 텍스트입니다.

CE_MenuTearOffCE_MenuScroller 의 스타일 옵션 설정은 QStyleOptionMenuItem 을 사용하며, QStyleOptioninitFrom()를 사용한 공통 설정 외에 menuRect 변수만 설정합니다.

QMenuBar 는 스타일을 사용하여 각 메뉴 모음 항목과 메뉴 모음의 빈 영역을 그립니다. 풀다운 메뉴 자체는 QMenus입니다( 메뉴 참조). 메뉴 표시줄의 스타일 요소 트리는 다음과 같습니다:

패널과 빈 영역은 메뉴 항목 다음에 그려집니다. QMenuBar 에서 스타일로 전송하는 QPainter 에는 항목의 경계 사각형이 잘려져 있으므로(즉, 클립 영역) 항목 위에 그리는 것에 대해 걱정할 필요가 없습니다. QMenuBar 의 픽셀 메트릭은 메뉴 모음 항목의 경계 사각형이 계산될 때 사용됩니다.

QStyleOptionMenuItem 는 메뉴 모음 항목에 사용됩니다. QMenuBar 에서 사용하는 멤버는 다음 표에 설명되어 있습니다:

멤버내용
menuRect항목이 속한 전체 메뉴 표시줄의 경계 사각형입니다.
text항목의 텍스트입니다.
아이콘메뉴 항목의 아이콘입니다(스타일이 이 아이콘을 그리는 것은 일반적이지 않습니다).

QStyleOptionMenuItem CE_EmptyMenuBarArea .

QStyleOptionFrame 는 패널 프레임을 그리는 데 사용됩니다. lineWidthPM_MenuBarPanelWidth 으로 설정됩니다. midLineWidth 은 현재 항상 0으로 설정되어 있습니다.

항목 보기 헤더

Qt의 항목 뷰의 헤더를 그리는 스타일입니다. 항목 뷰는 개별 섹션의 치수를 유지합니다. 또한 델리게이트는 이 스타일을 사용하여 항목 주위에 장식과 프레임을 그릴 수 있습니다. QItemDelegate 예를 들어 PE_FrameFocusRectPE_IndicatorItemViewItemCheck 을 그립니다.

다음은 Java 헤더의 경계 레트를 보여주는 QTableWidget 입니다:

QHeaderView 은 크기 및 히트 테스트 계산을 위해 CT_HeaderSection, PM_HeaderMarginPM_HeaderGripMargin 을 사용합니다. PM_HeaderMarkSize QTableView 은 왼쪽 상단 모서리(즉, 세로 및 가로 헤더가 교차하는 영역)에 있는 버튼을 CE_Header 으로 그립니다.

헤더 뷰의 스타일 옵션은 QStyleOptionHeader 입니다. 이 뷰는 한 번에 하나의 헤더 섹션을 그리므로 데이터는 그리는 섹션에 대한 것입니다. 내용은 다음과 같습니다:

Member콘텐츠
아이콘머리글의 아이콘(그리기 중인 섹션의 경우)입니다.
icon배열헤더에 있는 아이콘의 정렬(Qt::Alignment)입니다.
orientation헤더가 뷰 위의 가로 헤더인지 왼쪽의 세로 헤더인지 결정하는 Qt::Orientation 값입니다.
위치다른 섹션에 대한 헤더 섹션의 위치를 나타내는 QStyleOptionHeader::SectionPosition 값입니다.
섹션그려지고 있는 섹션을 보유합니다.
selectedPosition그려지고 있는 섹션을 기준으로 선택한 섹션의 위치를 나타내는 QStyleOptionHeader::SelectedPosition 값입니다.
정렬 표시기섹션의 정렬 표시기가 그려질 방향을 설명하는 QStyleOptionHeader::SortIndicator 값입니다.
text현재 그려진 섹션의 텍스트입니다.
textAlignment헤더 섹션 내 텍스트의 Qt::Alignment 값입니다.

트리 분기 표시기

트리 뷰의 분기 표시기는 PE_IndicatorBranch 스타일로 그려집니다. 여기서 표시기는 트리에서 노드의 관계를 설명하는 표시기로 생각하면 됩니다. 이러한 요소를 그리기 위해 일반 QStyleOption 이 스타일로 전송됩니다. 다양한 분기 유형은 상태로 설명됩니다. 특정 스타일 옵션이 없으므로 단순히 상태 테이블을 제시합니다:

상태설정 시기
State_Sibling트리의 노드에 형제 노드가 있는 경우(즉, 같은 열에 다른 노드가 있는 경우).
State_Item이 브랜치 표시기에 항목이 있습니다.
State_Children분기에 자식이 있는 경우(즉, 분기에서 새 하위 트리를 열 수 있음).
State_Open분기 표시기에 열린 하위 트리가 있습니다.

트리 보기(및 트리 위젯)는 스타일을 사용하여 트리의 가지(노드)를 그립니다.

QStyleOption PE_IndicatorBranch 의 스타일은 분기 유형에 따라 상태 플래그가 설정되어 있으므로 사용됩니다.

분기 표시기에 대한 트리 구조가 없으므로 Java 스타일로 트리 이미지만 표시합니다. 각 상태는 이미지에서 특정 색상의 직사각형으로 표시됩니다(즉, 직사각형은 경계가 없는 직사각형이 아님). 알아야 하는 모든 상태의 조합이 이미지에 표시됩니다.

도구 상자

PM_SmallIconSize 의 경우 크기 힌트

QToolBox 는 위젯 컬렉션을 보관하는 컨테이너입니다. 각 위젯에 대해 하나의 탭이 있으며 한 번에 하나의 위젯을 표시합니다. 도구 상자는 표시되는 구성 요소(도구 상자 버튼 및 선택한 위젯)를 QVBoxLayout. 도구 상자의 스타일 트리는 다음과 같습니다:

도구 상자의 이미지가 플라스티크 스타일로 표시됩니다:

모든 요소는 다른 기본 제공 Qt 스타일뿐만 아니라 Plastique 스타일에서도 동일한 경계 직사각형을 가집니다.

도구 상자의 스타일 옵션은 QStyleOptionToolBox 입니다. 여기에는 도구 상자 콘텐츠의 텍스트와 아이콘이 포함됩니다. QToolBox 에서 설정하는 유일한 상태는 State_Sunken 이며, 사용자가 마우스로 탭을 아래로 누를 때 설정됩니다. 나머지 QStyleOptionToolBox 멤버는 다음과 같습니다:

멤버콘텐츠
아이콘도구 상자 탭의 아이콘입니다.
텍스트도구 상자 탭의 텍스트입니다.

크기 그립

크기 그립은 CT_SizeGrip 를 사용하여 크기 힌트를 계산합니다. 픽셀 메트릭 PM_SizeGripSize 은 현재 Qt XML에서 사용되지 않습니다. Plastique 스타일의 이미지에 대한 요소 트리는 QSizeGrip 입니다:

QMainWindow 의 오른쪽 하단 모서리에 크기 그립이 표시됩니다.

크기 그립 스타일 옵션인 QStyleOptionSizeGrip 에는 QStyleOption 의 공통 멤버 외에 하나의 멤버가 있습니다:

Member콘텐츠
코너창에서 그립이 위치한 모서리(또는 이와 동등한 위치)를 설명하는 Qt::Corner 값입니다.

고무줄

QRubberBand 의 스타일 트리는 두 개의 노드로 구성됩니다.

여기서는 고무줄이 있는 QMdiArea 에서 자바 스타일 창을 이동하는 이미지를 제시합니다:

고무줄의 스타일 옵션은 QStyleOptionRubberBand 입니다. 그 멤버는 다음과 같습니다:

MemberContent
opaque고무줄을 불투명한 스타일(즉, 색상)로 그려야 하는 경우 true 인 부울입니다.
모양밴드의 모양(직사각형 또는 선)을 나타내는 QRubberBand::Shape 열거형 값입니다.

도크 위젯

도크 위젯이 콘텐츠를 배치할 때 다음 픽셀 메트릭에 대한 스타일을 묻습니다: PM_DockWidgetSeparatorExtent, PM_DockWidgetTitleBarButtonMargin, PM_DockWidgetFrameWidth, PM_DockWidgetTitleMargin 를 사용하여 플로트 및 닫기 버튼의 경계 직사각형을 계산하고 SE_DockWidgetCloseButtonSE_DockWidgetFloatButton 를 사용하여 닫기 버튼의 경계 직사각형을 계산합니다.

점선은 발신자가 화살표 수신자의 인스턴스를 유지한다는 것을 나타냅니다(즉, 그릴 스타일 요소가 아님). 도킹 위젯은 기본 창에서 분리된 경우(즉, 최상위 창인 경우) PE_frameDockWidget 만 그립니다. 도킹되어 있으면 표시기 도크 위젯 크기 조정 핸들을 그립니다. 도크 위젯은 플라스티크 스타일로 도킹된 상태와 플로팅 상태 모두에 표시됩니다:

스타일 옵션은 QStyleOptionDockWidget 입니다:

Member콘텐츠
closeable도크 창을 닫을 수 있는지 여부를 나타내는 부울입니다.
floatable도크 창을 띄울 수 있는지(즉, 도크 창이 있는 메인 창에서 분리할 수 있는지) 여부를 나타내는 부울입니다.
movable창이 움직일 수 있는지 여부(즉, 다른 도크 위젯 영역으로 이동할 수 있는지 여부)를 나타내는 부울입니다.
title도크 창의 제목 텍스트입니다.

버튼의 경우 QStyleOptionButton 가 사용됩니다(콘텐츠 설명은 도구 버튼 참조). 도크 위젯 크기 조정 핸들은 일반 QStyleOption 입니다.

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