- 2023년 2월 24일
- Volker Hilsheimer
- https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5
최근 Windows 10 빌드와 Windows 11의 경우 어두운 색 구성표가 마침내 Windows 데스크톱의 주류 개인화 옵션으로 자리 잡았습니다. Qt는 수년 동안 macOS에서 어두운 모양 설정을 지원했으며 Qt 6.5에서는 Windows에서도 어두운 테마에 대한 더 나은 지원을 제공합니다.
Windows에서 테마 및 개인 설정은 오랜 역사를 가지고 있습니다. Windows 3.1에는 이미 맞춤형 마우스 커서와 아이콘 패키지가 있었고 최신 영화에서 영감을 받은 배경 이미지와 음향 효과로 여러 플로피와 최신 DVD를 채웠습니다.
적절한 UI 테마는 시스템 라이브러리의 Win32 API를 통해 Windows XP에 도입되었습니다. 저는 2001년 바르셀로나에서 열린 Microsoft의 TechEd 컨퍼런스에 참석하여 시간이 지남에 따라 해당 프레임워크에서 무엇을 기대할 수 있는지 알아보았습니다. MFC 또는 Win32 API를 사용하여 사용자 지정 컨트롤을 개발한 청중에게 가능성은 무한하고 두려운 것처럼 보였습니다. 둥근 UI 요소, 구멍이 있는 버튼, 그래디언트, 반투명, 심지어 애니메이션에 대한 이야기를 기억합니다! UxTheme
우리는 이미 Windows XP 프리뷰 빌드를 기반으로 Qt의 Windows XP 스타일 구현 작업을 하고 있었고 새로운 기본 API를 사용하여 사용자 인터페이스 컨트롤의 다양한 요소를 그렸습니다. 그 작업은 곧 출시될 Qt 3 릴리스에 맞춰 많은 API 설계에 영향을 미쳤습니다. 그리고 API는 여전히 Qt 6의 . Windows XP 스타일의 구현은 나중에 Windows Vista 스타일의 기반이 되었으며 Qt 6의 경우 Qt Quick Controls의 기본 Windows 데스크톱 스타일에서 해당 구현을 사용합니다. QStyle QStyle QtWidgets
그러나 패션은 변하고 모든 기술이 원래 의도한 대로 진화하는 것은 아닙니다. 크리에이터 커뮤니티가 많은 커서 및 아이콘 라이브러리와 유사하게 라이브러리에 대한 많은 사용자 정의 UI 테마를 구축할 것이라는 기대가 있었을 것입니다 . 그런 일은 실제로 일어나지 않았고, 오늘날 버튼은 모서리가 둥근 평평한 프레임이지만 다행스럽게도 여전히 구멍이 없는 것 같습니다. UxTheme
API 는 여전히 Windows 11에 있으며 Qt는 여전히 이를 사용하여 기본 Windows Vista 스타일의 사용자 인터페이스 컨트롤 요소를 렌더링합니다. 그러나 우리가 얻는 컨트롤 자산은 여전히 Windows Vista의 Aero 디자인 시스템을 기반으로 합니다. 그리고 그 디자인 시스템에는 "다크 모드"가 없으며 해당 API를 통해 다크 컨트롤 자산을 얻을 수 있는 문서화된 방법이 없습니다. 따라서 Qt는 시스템에서 어두운 팔레트를 읽을 수 있지만 기반 Vista 스타일이 사용될 때는 실제로 사용할 수 없습니다. 일부 UI 요소에 대해 어두운 테마 색상을 얻을 수 있지만 시스템에서 가벼운 UI 제어 자산을 얻을 수 있습니다. 사용할 수 없는 사용자 인터페이스를 가진 사용자. UxTheme UxTheme
최근 몇 년 동안 Microsoft는 Windows 11 시스템 UI의 기반이 되는 Fluent 디자인 시스템 으로 이동했습니다. 그러나 해당 시스템은 를 통해 사용할 수 없으므로 Windows 11 시스템에서 운영 체제 UI조차 다양한 스타일로 제공되는 것은 놀라운 일이 아닙니다. 상대적으로 새로운 라이브러리로 작성되지 않은 응용 프로그램 및 시스템 대화 상자는 "유창하게" 보이지 않고 종종 어두운 색 구성표를 지원하지 않으며 트리의 더 아래에 있는 일부 제어판은 여전히 Windows 2000에서 사용했던 것처럼 보입니다. UxTheme WinUI
버전 5.15부터 Qt는 어두운 시스템 팔레트를 사용하거나 적어도 창 장식을 위해 어두운 시스템 테마를 존중하는 옵트인 방식을 제공했습니다. 해당 옵트인은 QPA 플랫폼에 대한 매개변수 이며 애플리케이션을 시작할 때 명령줄 옵션을 통해 설정할 수 있습니다.
> gallery.exe -platform windows:darkmode=1
> gallery.exe -platform windows:darkmode=2
또는 환경 변수를 통해(바람직하게는 를 통해 기본 기능에서 설정 ). qsetenv("QT_QPA_PLATFORM", "windows:darkmode=[1|2]")
값 '1'은 창 장식 테마를 활성화하여 사용자 지정 팔레트와 해당 스타일을 구현하는 응용 프로그램이 일관된 창 프레임과 제목 표시줄을 가질 수 있도록 합니다. 또한 값 '2'는 Qt가 어두운 시스템 팔레트를 읽고 사용하게 합니다. Qt 6.4까지의 기본값은 둘 다 지원하지 않는 것이었습니다. darkmode
Qt 6.4에서는 응용 프로그램 기본 팔레트에 따라 기본 동작을 변경했습니다. 응용 프로그램 팔레트가 어두우면 창은 자동으로 어두운 창 장식을 사용합니다. 팔레트가 어두운지 밝은지 확인하기 위해 창 색상과 텍스트 색상을 비교합니다.
static bool shouldApplyDarkFrame()
{
// ...
const QPalette defaultPalette;
return defaultPalette.color(QPalette::WindowText).lightness()
> defaultPalette.color(QPalette::Window).lightness();
}
그런 다음 응용 프로그램은 어두운 팔레트와 잘 어울리는 스타일을 사용하고 어두운 팔레트를 설정하고 어두운 창 제목과 프레임을 자동으로 가져올 수 있습니다.
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setStyle("fusion"); // looks good with dark color scheme
app.setPalette(myDarkPalette());
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
문제는 여전히 어두운 팔레트가 시스템에서 읽히지 않고 지정되지 않는 한 손으로 제작해야 한다는 것입니다. 가 지정되면 스타일이 어두운 색 구성표로 작업할 수 없는 경우에도 어두운 팔레트가 사용됩니다. 또한 시스템이 어둡거나 밝은 색 구성표로 실행 중인지 확인하는 Qt API가 없습니다. darkmode=2 darkmode=2
Qt 6.5에서 우리는 기존 애플리케이션에 대해 변경되지 않은 상태를 유지하면서 다음 단계로 나아가고 있습니다.
QStyleHints 열거 형 값을 보유하는 새 속성 또는 또는 (또는 해당 시스템 색 구성표가 없는 시스템에서)가 있습니다. 이를 통해 응용 프로그램은 사용자의 시스템 기본 설정을 고려하여 손으로 만든 응용 프로그램 팔레트가 어둡거나 밝아야 하는지 여부를 결정할 수 있습니다. 모든 좋은 속성과 마찬가지로 응용 프로그램이 시스템 색 구성표의 변경에 응답할 수 있도록 하는 변경 알림 신호가 함께 제공됩니다 . colorScheme Qt::ColorScheme Qt::ColorScheme::Light Qt::ColorScheme::Dark Qt::ColorScheme::Unknown QStyleHints::colorSchemeChanged
그러나 이상적으로는 더 이상 팔레트를 손으로 만들 필요가 없습니다. 특히 고대비 사용자 인터페이스가 필요한 사용자를 고려할 때 사용자 기본 설정을 무시하는 것은 솔직히 미끄러운 경사입니다.
Qt는 이제 사용자의 기본 설정을 기반으로 하는 시스템 팔레트를 항상 로드합니다. Qt 6.5에서도 Gnome 데스크탑에서도 마찬가지입니다. 그러나 위에서 설명한 것처럼 모든 스타일이 어떤 팔레트와도 잘 어울리는 것은 아니며 Windows Vista 스타일도 그럴 수 없습니다. 따라서 스타일은 해당 시스템 팔레트를 무시하고 기존 광택 인프라(및 Qt Quick 스타일의 동등한 테마 재정의)를 사용하여 다른 팔레트로 덮어쓸 수 있습니다 . Windows Vista 스타일은 항상 시스템 팔레트를 조명 시스템 팔레트로 대체합니다. "Fusion" 또는 클래식 Windows 스타일과 같이 모든 팔레트와 잘 작동하는 스타일은 응용 프로그램 팔레트를 수정하지 않은 상태로 둡니다. QStyle
이 스크린샷은 위젯 "갤러리" 예제를 보여줍니다(내 로컬 dev 브랜치에서 가져온 것이지만 Qt 6.5 베타 패키지에서도 동일한 결과를 얻을 수 있습니다). 왼쪽에는 기본 Windows 스타일이 실행되고 있고 오른쪽에는 -style fusion 명령줄 옵션으로 시작되었습니다. 우리는 Windows의 Qt에서 기본 스타일을 변경하지 않으므로 기본적으로 응용 프로그램은 어두운 테마로 실행되는 Windows 11 시스템에서도 밝은 시스템 팔레트를 사용하는 Windows Vista 스타일을 사용합니다. 창 프레임은 응용 프로그램 팔레트와 일치합니다.
그러나 이제 응용 프로그램은 개인 색 구성표에 대한 사용자의 기본 설정을 존중하면서 쉽게 어두운 모드 지원을 활성화할 수 있습니다. 작동하는 스타일만 설정하면 됩니다. Qt Quick 애플리케이션에서 다음과 같습니다.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
using namespace Qt::StringLiterals;
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickStyle::setStyle("fusion");
QQmlApplicationEngine engine;
engine.load(QUrl(u"qrc:/main.qml"_s));
return app.exec();
}
퓨전 스타일은 Windows 11에서 선호하는 스타일입니다. 어둡고 밝은 팔레트와 잘 어울리고 Fluent 디자인 언어를 사용하지는 않지만 Windows 11 데스크톱과 잘 어울립니다.
어두운 색 구성표 지원을 선택하기 전에 애플리케이션에서 확인해야 할 몇 가지 사항이 있습니다.
고유한 스타일을 작성했거나 스타일 시트를 사용하는 경우 특정 색상을 하드코딩할 수 있습니다. 예를 들어 비활성화된 버튼의 텍스트를 "회색으로 표시"하기 위해 약간 더 밝게 만드는 것은 드문 일이 아닙니다. 그러나 색 구성표가 어두우면 일반적으로 밝은 텍스트를 약간 더 어둡게 만들고 싶을 것입니다.
그리고 응용 프로그램이 그래프와 같은 특정 시각적 요소에 대해 사용자 정의 색상을 정의하는 경우 선택한 색상이 배경이 어둡고 전경이 밝을 때 의미가 있는지 확인해야 합니다. 하드 코딩된 색상을 포함할 수 있는 서식 있는 텍스트를 표시할 때와 같이 특정 UI 요소에 대해 어두운 팔레트와 밝은 팔레트 사이를 전환할 수 있는 옵션을 사용자에게 제공하는 것도 고려할 수 있습니다.
다음 버전의 Qt에 추가할 수 있는 몇 가지 단순하지만 반드시 쉬운 것은 아닙니다.
팔레트가 어두운지 밝은지 결정하기 위해 팔레트의 색상을 평가하는 QPalette::colorScheme 멤버를 추가할 수 있습니다 . 사용자 지정 시각적 요소에 대한 응용 프로그램의 색상 선택은 QStyleHints::colorScheme 값 이 아닌 사용된 실제 팔레트를 기반으로 해야 합니다 . 위의 간단한 shouldApplyDarkFrame() 도우미와 같은 멤버 함수를 사용하면 쉽게 할 수 있습니다.
일반적인 요청은 QStyleHints::colorScheme을 쓰기 가능한 속성으로 만들어 응용 프로그램이 시스템 설정에 관계없이 창 프레임을 포함하여 특정 색 구성표를 강제로 적용할 수 있도록 하는 것입니다. 이것은 일부 플랫폼에서 제한이 있을 것입니다. Windows에서는 밝은 시스템에서 어두운 창 장식을 강제하는 것이 불가능하다고 생각하지만 macOS에서는 각 창의 모양을 개별적으로 제어할 수 있습니다.
Windows에서 어두운 시스템 팔레트를 읽을 때 색상 역할에 테마의 강조 색상을 사용합니다. 그러나 Accent는 다른 곳에서도 사용되고 일부 컨트롤은 다른 색상을 사용하기 때문에 정확하지 않습니다(예: Windows 11의 "빨간색" 어두운 테마에서 강조 표시는 밝은 빨간색이고 초점 프레임은 옅은 주황색임). ). QPalette에는 현재 색상 역할이 없으며 내부 QPalette 데이터 구조가 21가지 색상 역할을 초과하면 상당히 변경해야 하므로 추가하는 것이 약간 복잡합니다. 이미 21가지입니다. QPalette::Highlight Accent
그리고 Fluent 디자인 시스템을 구현하는 스타일을 Qt에도 도입하고자 합니다. Fluent 디자인 시스템은 오픈 소스 Figma 패키지 로 제공되며 Brook은 최근 Qt Quick Controls와 함께 Figma 디자인을 사용하는 방법에 대해 블로그에 올렸습니다 . 이것이 우리가 지금 더 나아가고 있는 길입니다. Figma 디자인의 시각적 자산을 Qt Quick 사용자 인터페이스와 QtWidgets UI에서도 사용할 수 있게 만들고 싶습니다. 이는 가져오기/내보내기 브리지, Qt Design Studio 통합 및 빌드 시스템 도구를 혼합하여 달성할 수 있습니다. Microsoft에서 제공하는 Fluent 디자인을 기반으로 하는 Windows에서 Qt 응용 프로그램의 설득력 있는 기본 모양은 이 작업에 대한 좋은 벤치마크가 될 것입니다.
'Qt' 카테고리의 다른 글
Qt 5.15 수명 연장 (0) | 2024.05.09 |
---|---|
qtpip: Python용 상용 Qt 패키지를 얻는 간단한 도구 (0) | 2023.10.20 |
Qt는 이제 새로운 Android NDK 버전으로 최신 상태를 유지합니다 (0) | 2023.02.21 |
Qt 6으로 포팅 (0) | 2023.02.15 |
C++는 2022년 올해의 프로그래밍 언어입니다 (0) | 2023.01.30 |