본문으로 바로가기

Tk의 스크롤바(scrollbar)

category 카테고리 없음 2024. 4. 30. 14:01

스크롤바(scrollbar)는, 다른 위젯의 표시 영역을 제어하는 위젯입니다. 스크롤바와 연결 가능한 위젯은 canvas, entry, listbox, text 위젯들입니다. 각 위젯의 수평, 수직 스크롤의 연결 관계는 아래와 같습니다.

  • canvas  : X축, Y축 가능
  • entry   : X축 가능
  • listbox : X축, Y축 가능
  • text    : X축, Y축 가능

스크롤바와의 연결

아래는 listbox와 스크롤바를 연결시킨 예입니다. listbox 가장자리는,

-xscrollcommand {.f.x set} -yscrollcommand {.f.y set}

의 처리가, scrollbar의 가장자리는,

-command {.f.lst xview}

의 처리가 필요합니다. 스크롤바의 방향에는, 수평과 수직만 있기 때문에 -orient로 방향을 지정합니다. 양자를 연결한 후는 자동적으로 연동됩니다.

pack [frame .f] -fill both -expand 1
listbox .f.lst -xscrollcommand {.f.x set} -yscrollcommand {.f.y set}
scrollbar .f.x -command {.f.lst xview} -orient horizontal
scrollbar .f.y -command {.f.lst yview} -orient vertical

grid .f.lst .f.y -sticky news
grid .f.x -sticky news
grid rowconfigure .f 0 -weight 1
grid columnconfigure .f 0 -weight 1

.f.lst insert end 하나 둘 셋 넷
.f.lst selection set 0

두개의 위젯을 한 개의 스크롤바로 제어하기

아래는 두개의 listbox를 한 개의 스크롤바로 제어하는 예입니다. listbox의 선택 기능도 포함하기 때문에 코드가 조금 됩니다.

pack [frame .f] -fill both -expand 1
set BOXES [list .f.lst1 .f.lst2]

proc LBset args {
        global BOXES
        foreach lb $BOXES { eval $lb $args }
}

proc LBselect {sellist} {
        global BOXES
        foreach lb $BOXES {
                $lb selection clear 0 end
                foreach item $sellist {
                        $lb selection set $item
                }
        }
}

proc LBscroll args {
        eval .f.y set $args
        LBset yview moveto [lindex $args 0]
}

listbox .f.lst1 -yscrollcommand LBscroll -exportselection no
listbox .f.lst2 -yscrollcommand LBscroll -exportselection no
scrollbar .f.y -command {LBset yview}  -orient vertical

foreach lb $BOXES {
        bind $lb <<ListboxSelect>> {
                LBselect [%W curselection]
        }
}

grid .f.lst1 .f.lst2 .f.y -sticky news
grid rowconfigure .f 0 -weight 1
grid columnconfigure .f 0 -weight 1
grid rowconfigure .f 0 -weight 1
grid columnconfigure .f 1 -weight 1

.f.lst1 insert end 귤 사과 바나나
.f.lst2 insert end 500원 1000원 700원
.f.lst1 selection set 0
.f.lst2 selection set 0

필요시만 스크롤바 표시하기

아래는, listbox의 스크롤바를 필요시만 표시한 예입니다.

proc LBscroll {scrollbar geoCmd offset size} {
        if {$offset != 0.0 || $size != 1.0} {
                eval $geoCmd
                $scrollbar set $offset $size
        } else {
                grid forget $scrollbar
        }
}
pack [frame .f] -fill both -expand 1

listbox .f.lst \
        -xscrollcommand {LBscroll .f.x \
        {grid .f.x -row 1 -column 0 -sticky we}} \
        -yscrollcommand {LBscroll .f.y \
        {grid .f.y -row 0 -column 1 -sticky ns}}
scrollbar .f.x -command {.f.lst xview} -orient horizontal
scrollbar .f.y -command {.f.lst yview} -orient vertical

grid .f.lst .f.y -sticky news
grid .f.x -sticky news
grid rowconfigure .f 0 -weight 1
grid columnconfigure .f 0 -weight 1

.f.lst insert end 귤 사과 바나나
.f.lst selection set 0

포커스(focus) 설정

스크롤의 대상이 된 위젯에 focus를 주면, 디폴트 키바인드나, 화살표키, PgUP/PgDN 키 등의 스크롤도 할 수 있습니다. 또한 인텔리 마우스의 가운데 버튼의 스크롤도 가능합니다.

pack [frame .f] -fill both -expand 1
listbox .f.lst -xscrollcommand {.f.x set} -yscrollcommand {.f.y set}
scrollbar .f.x -command {.f.lst xview} -orient horizontal
scrollbar .f.y -command {.f.lst yview} -orient vertical

grid .f.lst .f.y -sticky news
grid .f.x -sticky news
grid rowconfigure .f 0 -weight 1
grid columnconfigure .f 0 -weight 1

.f.lst insert end 귤 사과 바나나
.f.lst selection set 0

bind .f.lst <1> {
        focus .f.lst
}
focus .f.lst