`focus` — 입력 포커스 관리하기
focus — 입력 포커스 관리하기
키보드 입력이 어느 위젯으로 갈지는 포커스가 결정해요. 창이 여러 개면 창 관리자가, 한 창 안에서는 애플리케이션이 어디로 포커스를 줄지 정해야 해요. focus 명령이 바로 그 입력 포커스를 조회하고 이동시키는 역할을 해요.
본문
시그니처
focus
focus window
focus option ?arg arg ...?
focus 명령은 Tk 입력 포커스를 관리해요. 어느 순간이든 각 디스플레이의 창 하나가 포커스 창(focus window)으로 지정되고, 그 디스플레이의 모든 키 누름·키 뗌 이벤트는 그 창으로 전송돼요.
보통 창 관리자가 디스플레이의 최상위 창들 사이에서 포커스를 옮겨 줘요. 예를 들어 어떤 창 관리자는 마우스가 최상위 창에 들어올 때마다 자동으로 입력 포커스를 그곳에 두고, 다른 창 관리자는 사용자가 창을 클릭할 때만 포커스를 옮겨요. 보통 창 관리자는 최상위 창에만 포커스를 주고, 최상위 내부의 자식들 사이 포커스 이동은 애플리케이션이 담당해요.
Tk는 최상위마다 포커스 창 하나를 기억해요(그 최상위에서 가장 최근에 포커스를 받은 하위 창). 창 관리자가 어떤 최상위에 포커스를 주면 Tk는 자동으로 그 기억된 창으로 포커스를 되돌려 줘요. 최상위 내부에서 Tk는 기본적으로 명시적(explicit) 포커스 모델을 써요. 최상위 안에서 마우스를 움직인다고 포커스가 바뀌지 않고, 위젯이 명시적으로 포커스를 요구할 때(예: 버튼 클릭 때문에)나 사용자가 Tab 같은 키를 눌러 포커스를 이동할 때만 바뀌어요.
Tcl 프로시저 tk_focusFollowsMouse를 호출하면 암시적(implicit) 포커스 모델을 만들 수 있어요. 마우스가 창에 들어올 때마다 그 창으로 포커스를 설정하도록 Tk를 재구성해요. Tcl 프로시저 tk_focusNext와 tk_focusPrev는 최상위 창들 사이의 포커스 순서를 구현하며, Tab·Shift-Tab의 기본 바인딩 등에 사용돼요.
사용 형태
focus — 애플리케이션 메인 창이 있는 디스플레이에서 포커스 창의 path name을 돌려줘요. 그 디스플레이의 이 애플리케이션 창 중 포커스를 가진 게 없으면 빈 문자열을 돌려줘요. 다중 디스플레이 앱에서도 동작하도록 -displayof(아래)로 디스플레이를 명시하는 게 좋아요.
focus window — 애플리케이션이 현재 window의 디스플레이에서 입력 포커스를 갖고 있다면, 그 디스플레이의 입력 포커스를 window로 재설정하고 빈 문자열을 돌려줘요. 만약 애플리케이션이 window의 디스플레이에서 입력 포커스를 갖고 있지 않다면, window는 그 최상위의 포커스로 기억돼요. 다음에 포커스가 그 최상위에 도달하면 Tk가 window로 되돌려 줘요. window가 빈 문자열이면 아무것도 하지 않아요.
focus -displayof window — window가 있는 디스플레이의 포커스 창 이름을 돌려줘요. window 디스플레이의 포커스 창이 이 애플리케이션에 없으면 빈 문자열을 돌려줘요.
focus -force window — 애플리케이션이 현재 그 디스플레이의 입력 포커스를 갖고 있지 않아도 window 디스플레이의 포커스를 window로 설정해요. 이 명령은 가급적 아껴 써야 해요. 정상적인 사용에서 애플리케이션은 포커스를 스스로 주장하지 말고 창 관리자가 주기를 기다려야 해요. window가 빈 문자열이면 아무것도 하지 않아요.
focus -lastfor window — window와 같은 최상위에 있는 모든 창 중 입력 포커스를 가장 최근에 가진 창의 이름을 돌려줘요. 그 최상위에서 포커스를 가진 적이 없거나, 가장 최근 포커스 창이 삭제됐다면 최상위의 이름을 돌려줘요. 돌려주는 창이 다음에 창 관리자가 최상위에 포커스를 줄 때 입력 포커스를 받을 창이에요.
특이 사항
내부 창이 입력 포커스를 받을 때 Tk는 실제로 X 포커스를 그 창으로 설정하지 않아요. X 입장에서 포커스는 포커스가 있는 창을 포함한 최상위 창에 계속 남아 있어요. 그러나 Tk는 마치 X 포커스가 내부 창에 있는 것처럼 FocusIn·FocusOut 이벤트를 만들어요. 이 방식은 X 포커스를 실제로 옮겼을 때 생기는 여러 문제를 피할 수 있어요. X 포커스가 최상위에 있다는 사실은 C 코드로 X 서버를 직접 질의하지 않으면 보이지 않아요.
예제
변수가 설정됐을 때만 포커스 순회 고리(traversal ring)에 참여하는 창을 만들려면, 그 포커스 고리에서 앞뒤의 위젯에 다음 바인딩을 추가하세요.
button .before -text "Before"
button .middle -text "Middle"
button .after -text "After"
checkbutton .flag -variable traverseToMiddle -takefocus 0
pack .flag -side left
pack .before .middle .after
bind .before <Tab> {
if {!$traverseToMiddle} {
focus .after
break
}
}
bind .after <Shift-Tab> {
if {!$traverseToMiddle} {
focus .before
break
}
}
focus .before
더 알아보기
tk_focusNext·tk_focusPrev·tk_focusFollowsMouse(focusNext 문서), bind, 그리고 창(포커스 창)에 대한 winfo 문서를 함께 보세요.