확장성
여러 가지 모바일 디바이스 플랫폼용 애플리케이션을 개발할 때 다음과 같은 문제에 직면하게 됩니다:
- 모바일 디바이스 플랫폼은 크기, 화면 비율, 방향, 밀도 등 다양한 화면 구성을 가진 디바이스를 지원합니다.
- 플랫폼마다 UI 규칙이 다르므로 각 플랫폼에서 사용자의 기대치를 충족시켜야 합니다.
Qt Quick 태블릿, 핸드셋 등 다양한 유형의 디바이스에서 실행할 수 있는 애플리케이션을 개발할 수 있습니다. 특히 다양한 화면 구성에 대응할 수 있습니다. 그러나 각 대상 플랫폼에 맞는 최적의 사용자 환경을 만들기 위해서는 항상 어느 정도의 수정과 다듬기가 필요합니다.
확장성을 고려해야 하는 경우
- Android, iOS 등 두 개 이상의 디바이스 플랫폼 또는 두 개 이상의 디바이스 화면 구성에 애플리케이션을 배포하려는 경우.
- 초기 배포 후 시장에 출시될 수 있는 새로운 디바이스에 대비하고자 하는 경우.
다음을 사용하여 확장 가능한 애플리케이션을 구현하려면 Qt Quick:
- 다음을 사용하여 UI 디자인 Qt Quick Controls 를 사용하여 UI를 디자인합니다.
- 항목 크기를 조정할 수 있는 Qt Quick 레이아웃을 사용하여 레이아웃을 정의합니다.
- 레이아웃에서 다루지 않는 사용 사례를 구현하려면 속성 바인딩을 사용합니다. 예를 들어, 픽셀 밀도가 낮거나 높은 화면에 대체 버전의 이미지를 표시하거나 현재 화면 방향에 따라 뷰 콘텐츠를 자동으로 조정할 수 있습니다.
- 참조 디바이스를 선택하고 이미지 및 글꼴 크기와 여백을 실제 화면 크기에 맞게 조정하기 위한 배율 비율을 계산합니다.
- 파일 선택기를 사용하여 플랫폼별 에셋을 로드합니다.
- 로더를 사용하여 필요에 따라 컴포넌트를 로드합니다.
애플리케이션을 디자인할 때 다음 패턴을 고려하세요:
- 뷰의 콘텐츠는 모든 화면 크기에서 매우 유사하지만 콘텐츠 영역이 확장된 경우. Qt Quick Controls 에서 ApplicationWindow QML 유형을 사용하는 경우 콘텐츠 항목의 크기에 따라 창 크기가 자동으로 계산됩니다. Qt Quick 레이아웃을 사용하여 콘텐츠 항목의 위치를 지정하면 푸시된 항목의 크기가 자동으로 조정됩니다.
- 작은 기기에서는 전체 페이지의 콘텐츠가 큰 기기에서는 레이아웃의 구성 요소를 형성할 수 있습니다. 따라서 이를 별도의 구성 요소로 만들고(즉, 별도의 QML 파일에 정의), 작은 기기에서는 뷰에 해당 구성 요소의 인스턴스가 포함되도록 하는 것이 좋습니다. 더 큰 기기에서는 로더를 사용하여 추가 항목을 표시할 수 있는 충분한 공간이 있을 수 있습니다. 예를 들어 이메일 뷰어에서 화면이 충분히 큰 경우 이메일 목록 보기와 이메일 리더 보기를 나란히 표시하는 것이 가능할 수 있습니다.
- 게임의 경우 일반적으로 큰 화면의 플레이어에게 불공평한 이점을 제공하지 않기 위해 크기가 조정되지 않는 게임 보드를 만들고 싶을 것입니다. 한 가지 해결책은 지원되는 가장 작은 화면 비율(일반적으로 3:2)의 화면에 맞는 안전 영역을 정의하고 4:3 또는 16:9 화면에서 숨겨질 공간에 장식 전용 콘텐츠를 추가하는 것입니다.
애플리케이션 창 크기 동적으로 조정하기
Qt Quick Controls 는 Qt Quick 에서 사용자 인터페이스를 만들기 위한 UI 컨트롤 세트를 제공합니다. 일반적으로 ApplicationWindow 컨트롤을 애플리케이션의 루트 항목으로 선언합니다. ApplicationWindow 은 MenuBar, ToolBar, StatusBar와 같은 다른 컨트롤을 플랫폼에 독립적인 방식으로 배치하는 데 편리함을 더합니다. ApplicationWindow 은 실제 창의 유효 크기 제약 조건을 계산할 때 콘텐츠 항목의 크기 제약 조건을 입력으로 사용합니다.
애플리케이션 창의 표준 부분을 정의하는 컨트롤 외에도 보기 및 메뉴를 생성하고 사용자의 입력을 표시하거나 수신하기 위한 컨트롤이 제공됩니다. Qt Quick Controls 스타일을 사용하여 미리 정의된 컨트롤에 사용자 지정 스타일을 적용할 수 있습니다.
Qt Quick Controls ToolBar 과 같은 컨트롤은 자체 레이아웃을 제공하지 않으며 콘텐츠의 위치를 지정해야 합니다. 이를 위해 레이아웃을 사용할 수 있습니다. Qt Quick
화면 컨트롤을 동적으로 배치하기
Qt Quick 레이아웃은 RowLayout, ColumnLayout, GridLayout QML 유형을 사용하여 행, 열 또는 그리드에 화면 컨트롤을 배치하는 방법을 제공합니다. 이러한 QML 유형의 속성은 레이아웃 방향과 셀 사이의 간격을 유지합니다.
Qt Quick 레이아웃 QML 유형을 사용하여 레이아웃에 푸시된 항목에 추가 속성을 첨부할 수 있습니다. 예를 들어 항목 높이, 너비 및 크기에 대한 최소, 최대 및 기본값을 지정할 수 있습니다.
레이아웃은 창과 화면의 크기를 조정할 때 UI의 크기가 적절하게 조정되고 항상 사용 가능한 최대 공간을 사용하도록 보장합니다.
GridLayout 유형의 구체적인 사용 사례는 화면 방향에 따라 행 또는 열로 사용하는 것입니다.
다음 코드 조각은 flow
속성을 사용하여 화면 너비가 화면 높이보다 클 경우 그리드의 흐름을 왼쪽에서 오른쪽으로(행으로), 그렇지 않은 경우 위에서 아래로(열로) 설정합니다:
ApplicationWindow { id: root visible: true width: 480 height: 620 GridLayout { anchors.fill: parent anchors.margins: 20 rowSpacing: 20 columnSpacing: 20 flow: width > height ? GridLayout.LeftToRight : GridLayout.TopToBottom Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: "#5d5b59" Label { anchors.centerIn: parent text: "Top or left" color: "white" } } Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: "#1e1b18" Label { anchors.centerIn: parent text: "Bottom or right" color: "white" } } } }
화면 크기를 계속 조정하고 다시 계산하면 성능 비용이 발생합니다. 예를 들어 모바일 및 임베디드 디바이스에는 매 프레임마다 애니메이션 개체의 크기와 위치를 다시 계산하는 데 필요한 성능이 없을 수 있습니다. 레이아웃을 사용할 때 성능 문제가 발생하면 대신 바인딩과 같은 다른 방법을 사용하는 것이 좋습니다.
다음은 레이아웃을 사용하지 말아야 할 몇 가지 사항입니다:
- 레이아웃의 목표와 충돌하고 바인딩 루프를 유발할 수 있으므로 레이아웃에 있는 항목의 x, y, 너비 또는 높이 속성에 바인딩을 사용하지 마세요.
- 정기적으로 평가되는 복잡한 자바스크립트 함수를 정의하지 마세요. 특히 애니메이션 전환 중에 성능이 저하될 수 있습니다.
- 컨테이너 크기나 하위 항목의 크기에 대해 가정하지 마세요. 사용 가능한 공간의 변화를 흡수할 수 있는 유연한 레이아웃 정의를 하세요.
- 디자인이 픽셀 단위로 완벽하기를 원한다면 레이아웃을 사용하지 마세요. 사용 가능한 공간에 따라 콘텐츠 항목의 크기와 위치가 자동으로 조정됩니다.
바인딩 사용
Qt Quick 레이아웃이 필요에 맞지 않는 경우 속성 바인딩을 사용할 수 있습니다. 바인딩을 사용하면 다른 객체의 속성이 변경되거나 외부 이벤트가 발생하면 객체의 속성을 자동으로 업데이트할 수 있습니다.
객체의 프로퍼티에 값을 할당할 때는 정적 값을 할당하거나 자바스크립트 표현식에 바인딩할 수 있습니다. 전자의 경우, 프로퍼티에 새 값이 할당되지 않는 한 프로퍼티의 값은 변경되지 않습니다. 후자의 경우, 속성 바인딩이 생성되고 평가된 표현식의 값이 변경될 때마다 QML 엔진에 의해 속성 값이 자동으로 업데이트됩니다.
이 유형의 위치 지정은 가장 동적인 방식입니다. 하지만 자바스크립트 표현식을 지속적으로 평가하는 데는 성능 비용이 발생합니다.
Android, macOS, iOS처럼 픽셀 밀도가 자동으로 지원되지 않는 플랫폼에서는 바인딩을 사용하여 낮은 픽셀 밀도와 높은 픽셀 밀도를 처리할 수 있습니다. 다음 코드 스니펫은 Screen.pixelDensity 첨부 속성을 사용하여 픽셀 밀도가 낮은 화면, 높은 화면 또는 일반 화면에 표시할 이미지를 다르게 지정합니다:
Image { source: { if (Screen.pixelDensity < 40) "image_low_dpi.png" else if (Screen.pixelDensity > 300) "image_high_dpi.png" else "image.png" } }
Android, macOS 및 iOS에서는 아이콘 및 이미지에 해당 식별자(예: @2x, @3x 또는 @4x)를 사용하여 더 높은 해상도의 대체 리소스를 제공하고 리소스 파일에 배치할 수 있습니다. 화면의 픽셀 밀도와 일치하는 버전이 자동으로 선택되어 사용됩니다.
예를 들어, 다음 코드 조각은 Retina 디스플레이에서 artwork@2x.png 로드를 시도합니다:
Image {
source: "artwork.png"
}
픽셀 밀도 처리하기
이미지, BorderImage, Text 와 같은 일부 QML 유형은 지정된 속성에 따라 자동으로 크기가 조정됩니다. 이미지의 너비와 높이가 지정되지 않은 경우 source
속성을 사용하여 지정한 소스 이미지의 크기가 자동으로 사용됩니다. 기본적으로 너비와 높이를 지정하면 이미지의 크기가 해당 크기로 조정됩니다. fillMode
속성을 설정하면 이 동작을 변경하여 이미지를 늘리거나 타일링할 수 있습니다. 그러나 높은 DPI 디스플레이에서는 원본 이미지 크기가 너무 작게 표시될 수 있습니다.
BorderImage 은 각 이미지의 일부를 확장하거나 타일링하여 이미지에 테두리를 만드는 데 사용됩니다. 소스 이미지를 속성 값에 따라 크기 조정 또는 타일링되는 9개 영역으로 나눕니다. 그러나 모서리의 크기가 전혀 조정되지 않으므로 DPI가 높은 디스플레이에서는 결과가 최적화되지 않을 수 있습니다.
Text QML 유형은 명시적으로 설정하지 않는 한 필요한 공간을 결정하고 그에 따라 width
및 height
속성을 설정하려고 시도합니다. fontPointSize
속성은 장치에 독립적인 방식으로 포인트 크기를 설정합니다. 그러나 글꼴을 포인트 단위로 지정하고 다른 크기를 픽셀 단위로 지정하면 포인트는 디스플레이 밀도와 무관하므로 문제가 발생할 수 있습니다. 낮은 DPI 디스플레이에서는 올바르게 보이는 문자열 주위의 프레임이 높은 DPI 디스플레이에서는 너무 작아져 텍스트가 잘릴 수 있습니다.
높은 DPI 지원 수준과 지원되는 플랫폼에서 사용하는 기술은 플랫폼마다 다릅니다. 다음 섹션에서는 고DPI 디스플레이에서 화면 콘텐츠의 크기를 조정하는 다양한 접근 방식에 대해 설명합니다.
Qt의 고 DPI 지원 및 지원되는 플랫폼에 대한 자세한 내용은 고 DPI를 참조하십시오.
macOS와 iOS에서의 고DPI 스케일링
macOS와 iOS에서 애플리케이션은 기존 DPI 스케일링의 대안으로 높은 DPI 스케일링을 사용합니다. 기존 방식에서는 애플리케이션에 글꼴 크기, 레이아웃 등을 곱하는 데 사용되는 DPI 값이 표시됩니다. 새로운 접근 방식에서는 운영 체제가 그래픽 출력의 크기를 조정하는 데 사용되는 스케일링 비율을 Qt에 제공합니다: 더 큰 버퍼를 할당하고 스케일링 변환을 설정합니다.
이 접근 방식의 장점은 벡터 그래픽과 글꼴의 크기가 자동으로 조정되고 기존 애플리케이션이 수정되지 않고 작동한다는 것입니다. 그러나 래스터 콘텐츠의 경우 고해상도 대체 리소스가 필요합니다.
스케일링은 QtQuick 및 QtWidgets 스택에서 구현되며, QtGui 및 Cocoa 플랫폼 플러그인에서도 일반적으로 지원됩니다.
OS는 창, 이벤트 및 데스크톱 지오메트리의 크기를 조정합니다. Cocoa 플랫폼 플러그인은 배율 비율을 QWindow::devicePixelRatio() 또는 QScreen::devicePixelRatio()로 설정하고 백킹 스토어에서 설정합니다.
QtWidgets의 경우 QPainter 은 백킹 스토어에서 devicePixelRatio()
을 가져와서 배율로 해석합니다.
그러나 OpenGL에서 픽셀은 항상 디바이스 픽셀입니다. 예를 들어 glViewport()로 전달된 지오메트리는 devicePixelRatio()로 배율을 조정해야 합니다.
지정된 글꼴 크기(포인트 또는 픽셀 단위)는 변경되지 않으며 문자열은 UI의 나머지 부분과 비교하여 상대적인 크기를 유지합니다. 글꼴은 페인팅의 일부로 크기가 조정되므로 포인트 또는 픽셀 단위로 지정되었는지 여부에 관계없이 크기 12 글꼴은 사실상 2배 배율이 적용된 크기 24 글꼴이 됩니다. 픽셀 단위는 장치에 독립적인 픽셀로 해석되어 높은 DPI 디스플레이에서 글꼴이 작게 표시되지 않도록 합니다.
배율 계산하기
하나의 높은 DPI 장치를 참조 장치로 선택하고 이미지 및 글꼴 크기와 여백을 실제 화면 크기에 맞게 조정하기 위한 배율을 계산할 수 있습니다.
다음 코드 조각은 Nexus 5 Android 디바이스의 DPI, 높이 및 너비에 대한 참조 값, QRect 클래스에서 반환하는 실제 화면 크기, qApp
글로벌 포인터에서 반환하는 화면의 논리적 DPI 값을 사용하여 이미지 크기 및 여백에 대한 배율 비율(m_ratio
)과 글꼴 크기(m_ratioFont
)을 계산합니다:
qreal refDpi = 216.; qreal refHeight = 1776.; qreal refWidth = 1080.; QRect rect = QGuiApplication::primaryScreen()->geometry(); qreal height = qMax(rect.width(), rect.height()); qreal width = qMin(rect.width(), rect.height()); qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch(); m_ratio = qMin(height/refHeight, width/refWidth); m_ratioFont = qMin(height*refDpi/(dpi*refHeight), width*refDpi/(dpi*refWidth));
적절한 배율을 위해 높이와 너비 값은 기준 디바이스의 기본 방향(이 경우 세로 방향)에 따라 설정해야 합니다.
다음 코드 스니펫은 글꼴 배율 비율이 1보다 작아 글꼴 크기가 너무 작아지는 경우 1
로 설정합니다:
int tempTimeColumnWidth = 600; int tempTrackHeaderWidth = 270; if (m_ratioFont < 1.) { m_ratioFont = 1;
대상 디바이스를 실험하여 추가 계산이 필요한 엣지 케이스를 찾아야 합니다. 일부 화면은 너무 짧거나 좁아서 계획한 모든 콘텐츠를 담을 수 없으므로 자체 레이아웃이 필요할 수 있습니다. 예를 들어 1:1과 같은 비정형 화면 비율의 화면에서 일부 콘텐츠를 숨기거나 바꿔야 할 수도 있습니다.
배율은 QQmlPropertyMap 의 모든 크기에 적용하여 이미지, 글꼴 및 여백의 크기를 조정할 수 있습니다:
m_sizes = new QQmlPropertyMap(this); m_sizes->insert(QLatin1String("trackHeaderHeight"), QVariant(applyRatio(270))); m_sizes->insert(QLatin1String("trackHeaderWidth"), QVariant(applyRatio(tempTrackHeaderWidth))); m_sizes->insert(QLatin1String("timeColumnWidth"), QVariant(applyRatio(tempTimeColumnWidth))); m_sizes->insert(QLatin1String("conferenceHeaderHeight"), QVariant(applyRatio(158))); m_sizes->insert(QLatin1String("dayWidth"), QVariant(applyRatio(150))); m_sizes->insert(QLatin1String("favoriteImageHeight"), QVariant(applyRatio(76))); m_sizes->insert(QLatin1String("favoriteImageWidth"), QVariant(applyRatio(80))); m_sizes->insert(QLatin1String("titleHeight"), QVariant(applyRatio(60))); m_sizes->insert(QLatin1String("backHeight"), QVariant(applyRatio(74))); m_sizes->insert(QLatin1String("backWidth"), QVariant(applyRatio(42))); m_sizes->insert(QLatin1String("logoHeight"), QVariant(applyRatio(100))); m_sizes->insert(QLatin1String("logoWidth"), QVariant(applyRatio(286))); m_fonts = new QQmlPropertyMap(this); m_fonts->insert(QLatin1String("six_pt"), QVariant(applyFontRatio(9))); m_fonts->insert(QLatin1String("seven_pt"), QVariant(applyFontRatio(10))); m_fonts->insert(QLatin1String("eight_pt"), QVariant(applyFontRatio(12))); m_fonts->insert(QLatin1String("ten_pt"), QVariant(applyFontRatio(14))); m_fonts->insert(QLatin1String("twelve_pt"), QVariant(applyFontRatio(16))); m_margins = new QQmlPropertyMap(this); m_margins->insert(QLatin1String("five"), QVariant(applyRatio(5))); m_margins->insert(QLatin1String("seven"), QVariant(applyRatio(7))); m_margins->insert(QLatin1String("ten"), QVariant(applyRatio(10))); m_margins->insert(QLatin1String("fifteen"), QVariant(applyRatio(15))); m_margins->insert(QLatin1String("twenty"), QVariant(applyRatio(20))); m_margins->insert(QLatin1String("thirty"), QVariant(applyRatio(30)));
다음 코드 스니펫의 함수는 글꼴, 이미지 및 여백에 배율을 적용합니다:
int Theme::applyFontRatio(const int value) { return int(value * m_ratioFont); } int Theme::applyRatio(const int value) { return qMax(2, int(value * m_ratio)); }
이 기술은 대상 디바이스의 화면 크기가 크게 다르지 않을 때 합리적인 결과를 제공합니다. 차이가 크다면 서로 다른 기준값을 사용하여 여러 가지 레이아웃을 만드는 것이 좋습니다.
플랫폼에 따라 파일 로드하기
QQmlFileSelector 을 사용하여 QFileSelector 을 QML 파일 로딩에 적용할 수 있습니다. 이렇게 하면 애플리케이션이 실행되는 플랫폼에 따라 대체 리소스를 로드할 수 있습니다. 예를 들어 +android
파일 선택기를 사용하여 Android 기기에서 실행할 때 다른 이미지 파일을 로드할 수 있습니다.
파일 선택기를 싱글톤 객체와 함께 사용하여 특정 플랫폼에서 객체의 단일 인스턴스에 액세스할 수 있습니다.
파일 선택기는 정적이며 플랫폼별 파일이 플랫폼의 이름을 딴 하위 폴더에 저장되는 파일 구조를 적용합니다. 필요에 따라 UI의 일부를 로드하기 위해 보다 동적인 솔루션이 필요한 경우 로더를 사용할 수 있습니다.
대상 플랫폼은 다양한 방식으로 다양한 디스플레이 밀도에 대한 대체 리소스의 로딩을 자동화할 수 있습니다. Android 및 iOS에서 @2x 파일 이름 접미사는 이미지의 높은 DPI 버전을 나타내는 데 사용됩니다. 이미지 QML 유형과 QIcon 클래스는 @2x 버전의 이미지 및 아이콘이 제공된 경우 자동으로 로드합니다. QImage 및 QPixmap 클래스는 @2x 버전 이미지의 devicePixelRatio
을 2
으로 자동 설정하지만 실제로 @2x 버전을 사용하려면 코드를 추가해야 합니다:
if ( QGuiApplication::primaryScreen()->devicePixelRatio() >= 2 ) { imageVariant = "@2x"; } else { imageVariant = ""; }
안드로이드는 대체 리소스를 만들 수 있는 일반화된 화면 크기(작은, 보통, 큰, 큰, 큰)와 밀도(ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi)를 정의합니다. 안드로이드는 런타임에 현재 디바이스 구성을 감지하여 애플리케이션에 적합한 리소스를 로드합니다. 그러나 Android 3.2(API 레벨 13)부터 이러한 크기 그룹은 사용 가능한 화면 너비를 기반으로 화면 크기를 관리하는 새로운 기술을 위해 더 이상 사용되지 않습니다.
온디맨드 컴포넌트 로드
Loader 은 QML 파일( source
속성 사용) 또는 컴포넌트 객체( sourceComponent
속성 사용)를 로드할 수 있습니다. 이 기능은 컴포넌트가 필요할 때까지 컴포넌트 생성을 지연시키는 데 유용합니다. 예를 들어, 컴포넌트를 필요에 따라 생성해야 하거나 성능상의 이유로 불필요하게 생성하지 않아야 하는 경우에 유용합니다.
또한 로더를 사용하여 특정 플랫폼에서 일부 기능이 지원되지 않아 UI의 일부가 필요하지 않은 상황에 대응할 수도 있습니다. 애플리케이션이 실행 중인 디바이스에서 필요하지 않은 보기를 표시하는 대신 해당 보기가 숨겨져 있는지 확인하고 로더를 사용하여 그 자리에 다른 것을 표시할 수 있습니다.
방향 전환
Screen.orientation 첨부 속성에는 가속도계(사용 가능한 경우)에서 가져온 화면의 현재 방향이 포함됩니다. 데스크톱 컴퓨터에서는 일반적으로 이 값이 변경되지 않습니다.
primaryOrientation
이 orientation
을 따르는 경우 이는 디바이스를 잡는 방식에 따라 표시되는 모든 콘텐츠가 자동으로 회전한다는 의미입니다. primaryOrientation
은 변경되지 않는데 방향이 변경되면 디바이스 자체적으로 디스플레이가 회전하지 않을 수 있습니다. 이 경우 Item.rotation 또는 Item.transform 을 사용하여 콘텐츠를 회전해야 할 수 있습니다.
애플리케이션 최상위 페이지 정의와 재사용 가능한 컴포넌트 정의는 레이아웃 구조에 대해 하나의 QML 레이아웃 정의를 사용해야 합니다. 이 단일 정의에는 별도의 기기 방향 및 화면 비율에 대한 레이아웃 디자인이 포함되어야 합니다. 그 이유는 방향 전환 중 성능이 중요하기 때문에 방향이 변경될 때 두 방향에 필요한 모든 컴포넌트가 로드되도록 하는 것이 좋기 때문입니다.
반대로 Loader 를 사용하여 별도의 방향에 필요한 추가 QML을 로드하는 경우 방향 변경의 성능에 영향을 미치므로 철저한 테스트를 수행해야 합니다.
방향 간에 레이아웃 애니메이션을 사용하려면 앵커 정의가 동일한 포함 컴포넌트 내에 있어야 합니다. 따라서 페이지 또는 컴포넌트의 구조는 공통의 하위 컴포넌트 집합, 공통의 앵커 정의 집합, 컴포넌트가 지원하는 다양한 화면 비율을 나타내는 상태 모음( StateGroup)으로 구성되어야 합니다.
페이지에 포함된 컴포넌트가 다양한 폼 팩터 정의로 호스팅되어야 하는 경우 뷰의 레이아웃 상태는 페이지(바로 컨테이너)의 가로 세로 비율에 따라 달라져야 합니다. 마찬가지로 구성 요소의 여러 인스턴스가 UI의 여러 다른 컨테이너 내에 위치할 수 있으므로 레이아웃 상태는 부모의 화면 비율에 따라 결정되어야 합니다. 결론은 레이아웃 상태는 항상 현재 기기 화면의 '방향'이 아닌 직접 컨테이너의 종횡비를 따라야 한다는 것입니다.
각 레이아웃( State) 내에서 기본 QML 레이아웃 정의를 사용하여 항목 간의 관계를 정의해야 합니다. 자세한 내용은 아래를 참조하세요. 상태 간 전환 중(최상위 수준 방향 변경에 의해 트리거됨) 앵커 레이아웃의 경우 AnchorAnimation 요소를 사용하여 전환을 제어할 수 있습니다. 경우에 따라 항목의 너비 등에 NumberAnimation 요소를 사용할 수도 있습니다. 애니메이션의 각 프레임 동안 복잡한 자바스크립트 계산을 피해야 합니다. 대부분의 경우 간단한 앵커 정의와 앵커 애니메이션을 사용하면 도움이 될 수 있습니다.
고려해야 할 몇 가지 추가 사례가 있습니다:
- 가로와 세로가 완전히 다른, 즉 모든 하위 항목이 다른 단일 페이지가 있다면 어떻게 해야 할까요? 각 페이지에 대해 별도의 레이아웃 정의가 있는 두 개의 하위 컴포넌트를 만들고 각 상태에서 하나 또는 다른 항목의 불투명도를 0으로 설정합니다. 불투명도에 NumberAnimation 전환을 적용하여 교차 페이드 애니메이션을 사용할 수 있습니다.
- 하나의 페이지에서 가로와 세로 간에 동일한 레이아웃 콘텐츠의 30% 이상을 공유하는 페이지가 있다면 어떻게 해야 할까요? 이 경우 가로 및 세로 상태를 가진 하나의 컴포넌트와 방향 상태에 따라 불투명도(또는 위치)가 달라지는 별도의 하위 항목 모음을 사용하는 것이 좋습니다. 이렇게 하면 방향 간에 공유되는 항목에는 레이아웃 애니메이션을 사용하고 다른 항목은 페이드 인/아웃되거나 화면에서 애니메이션이 켜지거나 꺼지는 애니메이션을 사용할 수 있습니다.
- 더 큰 폼 팩터 디바이스와 같이 화면에 동시에 표시되어야 하는 두 페이지가 핸드헬드 디바이스에 있는 경우 어떻게 해야 할까요? 이 경우 보기 구성 요소가 더 이상 전체 화면을 차지하지 않는다는 점에 유의하세요. 따라서 모든 컴포넌트(특히 목록 델리게이트 항목)에서 화면 너비가 아닌 포함된 컴포넌트 너비의 크기에 따라 달라져야 한다는 점을 기억하는 것이 중요합니다. 이 경우 값이 설정되기 전에 목록 항목 델리게이트가 구성되었는지 확인하기 위해 Component.onCompleted() 핸들러에서 너비를 설정해야 할 수도 있습니다.
- 두 가지 방향이 메모리를 너무 많이 차지하여 한 번에 두 가지 방향을 모두 메모리에 넣을 수 없는 경우에는 어떻게 해야 하나요? 필요한 경우 두 가지 버전의 뷰를 한 번에 메모리에 보관할 수 없는 경우 Loader 를 사용하되 레이아웃 전환 중 교차 페이드 애니메이션의 성능에 주의하세요. 한 가지 해결책은 페이지의 하위 항목인 두 개의 '스플래시 화면' 항목을 만든 다음 회전하는 동안 두 항목 사이를 교차 페이드하는 것입니다. 그런 다음 Loader 을 사용하여 실제 모델 데이터를 다른 하위 항목에 로드하는 다른 하위 컴포넌트를 로드하고 Loader 이 완료되면 해당 항목으로 교차 페이드할 수 있습니다.
© 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.