QML
← 전체 컴포넌트

Drawer

창 가장자리에서 패널을 열어 상세 정보, 필터나 편집 화면을 표시합니다. 현재 페이지를 유지한 채 보조 작업을 제공할 때 사용합니다.

import Syidax.Core.Drawer

지원 QML 타입

타입정의 / 역할
창 가장자리에서 열리는 오버레이 패널입니다.

예제로 보기

미리보기는 Qt 실행 화면의 이미지입니다. 아래 버튼으로 결과를 전환하세요.

01 기본 구성

SyDrawer는 애플리케이션 창의 한 가장자리(position: 기본 right, 또는 left, top, bottom)에 붙어 마스크 위로 미끄러져 들어오는 패널입니다.

Qt 실행 화면 · 이미지
기본 구성 · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string position: "right"
        property string size: "medium"
        property int customSize: 100
        property string title: "필터"
        property bool closable: true
        property bool maskless: false
        property bool maskClosable: true
        property bool preventClose: false
        property string animation: "slide"
    }

    

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            position: storyArgs.position
            size: storyArgs.size
            customSize: storyArgs.customSize
            title: storyArgs.title
            closable: storyArgs.closable
            maskless: storyArgs.maskless
            maskClosable: storyArgs.maskClosable
            preventClose: storyArgs.preventClose
            animation: storyArgs.animation
            onOpened: output.log("opened")
            onClosed: output.log("closed")
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { id: exampleControl1;  text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }

}

02 header · footer

드로어에는 내용을 둘 자리가 셋 있습니다.

Qt 실행 화면 · 이미지
header · footer · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            title: "필터"
            closable: true
            open: true
            header: SyTag { text: "3개 적용"; size: "small" }
            footer: [
                SyButton { text: "초기화"; size: "small" },
                SyButton { text: "적용"; variant: "primary"; size: "small"; onClicked: drawer.setClose() }
            ]
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { text: "드로어 열기"; onClicked: drawer.setOpen() }
    }
}

03 opened · closed

- opened() — 패널이 완전히 들어오면 발생합니다: 진입 애니메이션 뒤, 또는 animation이 "none"이거나 Theme.reducedMotion이면 즉시.

Qt 실행 화면 · 이미지
opened · closed · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            title: "필터"
            closable: true
            animation: "slide"
            onOpened: { if (true) { output.log("opened") } }
            onClosed: { if (true) { output.log("closed") } }
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { id: exampleControl1;  text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }
}

04 setOpen · setClose

- setOpen() — open = true로 둡니다: 시트가 보이고, 패널이 자기 가장자리에서 진입을 재생하며, 시트가 키보드 포커스를 가져갑니다.

Qt 실행 화면 · 이미지
setOpen · setClose · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 24
        SyDrawer { id: drawer; title: "필터"; maskless: true; closable: true; Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled } }
        Row {
            spacing: 8
            SyButton { id: exampleControl1;  visible: true; text: "drawer.setOpen()"; variant: "secondary"; size: "small"; onClicked: drawer.setOpen() }
            SyButton { id: exampleControl2;  visible: true; text: "drawer.setClose()"; variant: "secondary"; size: "small"; onClicked: drawer.setClose() }
        }
        Text {
            text: "drawer.open === " + drawer.open + "   drawer.phase === " + JSON.stringify(drawer.phase)
            font.family: Theme.monoFontFamily
            font.pixelSize: 12
            color: Theme.semantic.textSubtle
        }
    }
}

05 왼쪽 탐색 서랍

position 설정을 적용한 왼쪽 탐색 서랍 예제입니다.

Qt 실행 화면 · 이미지
왼쪽 탐색 서랍 · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string position: "left"
        property string size: "medium"
        property int customSize: 100
        property string title: "필터"
        property bool closable: true
        property bool maskless: false
        property bool maskClosable: true
        property bool preventClose: false
        property string animation: "slide"
    }

    

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            position: storyArgs.position
            size: storyArgs.size
            customSize: storyArgs.customSize
            title: storyArgs.title
            closable: storyArgs.closable
            maskless: storyArgs.maskless
            maskClosable: storyArgs.maskClosable
            preventClose: storyArgs.preventClose
            animation: storyArgs.animation
            onOpened: output.log("opened")
            onClosed: output.log("closed")
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }

}

06 아래쪽 서랍

position · size · customSize 설정을 적용한 아래쪽 서랍 예제입니다.

Qt 실행 화면 · 이미지
아래쪽 서랍 · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string position: "bottom"
        property string size: "custom"
        property int customSize: 180
        property string title: "필터"
        property bool closable: true
        property bool maskless: false
        property bool maskClosable: true
        property bool preventClose: false
        property string animation: "slide"
    }

    

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            position: storyArgs.position
            size: storyArgs.size
            customSize: storyArgs.customSize
            title: storyArgs.title
            closable: storyArgs.closable
            maskless: storyArgs.maskless
            maskClosable: storyArgs.maskClosable
            preventClose: storyArgs.preventClose
            animation: storyArgs.animation
            onOpened: output.log("opened")
            onClosed: output.log("closed")
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }

}

07 위쪽 서랍

position · size · customSize 설정을 적용한 위쪽 서랍 예제입니다.

Qt 실행 화면 · 이미지
위쪽 서랍 · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string position: "top"
        property string size: "custom"
        property int customSize: 160
        property string title: "필터"
        property bool closable: true
        property bool maskless: false
        property bool maskClosable: true
        property bool preventClose: false
        property string animation: "slide"
    }

    

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            position: storyArgs.position
            size: storyArgs.size
            customSize: storyArgs.customSize
            title: storyArgs.title
            closable: storyArgs.closable
            maskless: storyArgs.maskless
            maskClosable: storyArgs.maskClosable
            preventClose: storyArgs.preventClose
            animation: storyArgs.animation
            onOpened: output.log("opened")
            onClosed: output.log("closed")
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }

}

08 마스크 없는 서랍

maskless 설정을 적용한 마스크 없는 서랍 예제입니다.

Qt 실행 화면 · 이미지
마스크 없는 서랍 · 열린 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string position: "right"
        property string size: "medium"
        property int customSize: 100
        property string title: "필터"
        property bool closable: true
        property bool maskless: true
        property bool maskClosable: true
        property bool preventClose: false
        property string animation: "slide"
    }

    

    Column {
        spacing: 12
        SyDrawer {
            id: drawer
            position: storyArgs.position
            size: storyArgs.size
            customSize: storyArgs.customSize
            title: storyArgs.title
            closable: storyArgs.closable
            maskless: storyArgs.maskless
            maskClosable: storyArgs.maskClosable
            preventClose: storyArgs.preventClose
            animation: storyArgs.animation
            onOpened: output.log("opened")
            onClosed: output.log("closed")
            Text { text: "상태와 담당자로 행을 거릅니다."; width: parent.width; wrapMode: Text.Wrap; font.family: Theme.fontFamily; font.pixelSize: 14; color: Theme.drawer.contentTextEnabled }
        }
        SyButton { text: "드로어 열기"; onClicked: drawer.setOpen() }
        EventLog { id: output }
    }

}

API 62

항목을 가리키거나 선택하면 QML 예제와 복사 버튼이 나타납니다.

속성

속성타입기본값설명
boolfalse드로어를 보임 / 숨김. setOpen() / setClose()가 설정.
string"right"붙는 가장자리: "top" · "left" · "right" · "bottom".
string"medium"깊이: "small" 150 · "medium" 300 · "large" 500 · "custom"(customSize).
real100size: "custom"일 때의 깊이(px).
string""헤더 글자.
list (alias)—제목 뒤의 아이템
list (alias)—푸터 행의 아이템.
——본문 아이템(12 px 여백, 잘림).
boolfalse헤더에 ×를 보임.
boolfalse마스크 없음. 뒤의 애플리케이션이 클릭됨.
booltrue마스크 클릭이 닫음(preventClose면 흔듦).
boolfalse마스크 클릭과 Escape는 pulse()만. setClose()와 ×는 여전히 닫음.
string"none"none · slide · slide-fade · fade · fade-scale · zoom · pop · slide-top/bottom/left/right · slide-fade-… · reveal.
string"fast"x-fast 100 · fast 150 · medium 250 · slow 350 · x-slow 500 ms.
colorTheme.semantic.backdropBackground마스크 색.
stringposition가장자리와 깊이에 바인딩. 다른 슬라이드가 필요하면 덮어쓰기.
realextent가장자리와 깊이에 바인딩. 다른 슬라이드가 필요하면 덮어쓰기.
real—결정된 깊이 · position이 left 또는 right.
bool (읽기 전용)—결정된 깊이 · position이 left 또는 right.
bool (읽기 전용)—헤더 / 푸터 행이 보이는지.
bool (읽기 전용)—헤더 / 푸터 행이 보이는지.
string"closed"closed · opening · open · closing · 시트가 보임.
bool (읽기 전용)"closed"closed · opening · open · closing · 시트가 보임.
Item (읽기 전용)—창 전체 크기의 시트.

메서드

메서드설명
open = true. 열려 있으면 효과 없음.
open = false. preventClose 무시. 닫혀 있으면 효과 없음.
패널을 축 방향으로 250 ms 동안 4 px 흔듦.

시그널

시그널인자시점
—진입이 끝남. 패널이 완전히 들어옴.
—종료가 끝남. 시트가 숨겨짐. 인자 없음 — 원인은 보고되지 않음.
—open이 바뀜(전환의 시작).
—maskClosable / preventClose와 무관하게, 패널 바깥 마스크의 클릭.
—시트에서 Escape, 닫기 / 흔들기 결정 전.
—opened / closed 뒤에 있는 베이스 시그널.
—opened / closed 뒤에 있는 베이스 시그널.

동작

항목동작 / 조건
드로어 아이템은 visible: false이며 부모 안에서 자리를 차지하지 않습니다.
드로어를 보임 / 숨김. setOpen() / setClose()가 설정.
open이 true가 되면 창 전체 크기의 시트(창 오버레이의 자식, z 100)가 마스크(mask, !maskless에 바인딩; maskColor)와 패널을 보이고 키보드 포커스를 가져갑니다.
마스크 없음. 뒤의 애플리케이션이 클릭됨.
마스크 색.
maskClosable / preventClose와 무관하게, 패널 바깥 마스크의 클릭.
붙는 가장자리: "top" · "left" · "right" · "bottom".
position이 패널을 붙입니다: left / right 패널은 창 높이만큼 높고 extent만큼 넓으며, top / bottom 패널은 창 폭만큼 넓고 extent만큼 높습니다. extent는 size small / medium / large에 150 / 300 / 500, custom에 customSize입니다. "slide"와 "slide-fade"는 드로어 자신의 가장자리와 전체 깊이를 씁니다(slideSide는 position에, slideDistance는 extent에 바인딩).
깊이: "small" 150 · "medium" 300 · "large" 500 · "custom"(customSize).
size: "custom"일 때의 깊이(px).
open = true. 열려 있으면 효과 없음.
헤더에 ×를 보임.
마스크 클릭이 닫음(preventClose면 흔듦).
open = false. preventClose 무시. 닫혀 있으면 효과 없음.
마스크 클릭과 Escape는 pulse()만. setClose()와 ×는 여전히 닫음.
패널을 축 방향으로 250 ms 동안 4 px 흔듦.
none · slide · slide-fade · fade · fade-scale · zoom · pop · slide-top/bottom/left/right · slide-fade-… · reveal.
"slide"와 "slide-fade"는 드로어 자신의 가장자리와 전체 깊이를 씁니다(slideSide는 position에, slideDistance는 extent에 바인딩).
"slide"와 "slide-fade"는 드로어 자신의 가장자리와 전체 깊이를 씁니다(slideSide는 position에, slideDistance는 extent에 바인딩).
x-fast 100 · fast 150 · medium 250 · slow 350 · x-slow 500 ms.
phase는 "closed" → "opening" → "open" → "closing"을 보고하고, opened()는 진입이 끝날 때, closed()는 종료가 끝날 때 발생합니다.
종료가 끝남. 시트가 숨겨짐. 인자 없음 — 원인은 보고되지 않음.
진입이 끝남. 패널이 완전히 들어옴.
헤더 글자.
헤더(44 px)는 title(16 px, 중간 굵기, 생략), header 아이템, 오른쪽의 ×를 보이며, 그중 하나라도 있을 때만 존재합니다.
본문은 12 px 여백에 잘리며, 안에 선언한 아이템은 width: parent.width를 바인딩해야 합니다.
푸터(44 px)는 footer 아이템을 오른쪽 정렬로 보이며 아이템이 있을 때만 존재합니다.

키보드

항목동작 / 조건
SyModal(같은 시트 베이스 위의 가운데 창), SyPopover(작은 앵커 패널), SyNav(안에 넣을 내비게이션 목록), SyTag / SyButton(흔한 헤더 / 푸터 아이템).