我使用以下代码来获得一个效果很好的滚动条:
(感谢:如何向tcl框架添加滚动条)
ttk::frame .frAlles
# create canvas with scrollbars
canvas .frAlles.c -width 400 -height 200 -xscrollcommand ".frAlles.xscroll set" -yscrollcommand ".frAlles.yscroll set"
ttk::scrollbar .frAlles.xscroll -orient horizontal -command ".frAlles.c xview"
ttk::scrollbar .frAlles.yscroll -command ".frAlles.c yview"
pack .frAlles.xscroll -side bottom -fill x
pack .frAlles.yscroll -side right -fill y
pack .frAlles.c -expand yes -fill both -side top
# create frame with widgets
ttk::frame .frAlles.c.frWidgets -borderwidth 1 -relief solid -width 340 -height 700
for {set i 0} {$i <=20} {incr i} {
ttk::label .frAlles.c.frWidgets.lb$i -text "Label $i:"
ttk::entry .frAlles.c.frWidgets.en$i
ttk::button .frAlles.c.frWidgets.bt$i -text "Button $i" -command exit
grid .frAlles.c.frWidgets.lb$i -padx 2 -pady 2 -row $i -column 0
grid .frAlles.c.frWidgets.en$i -padx 2 -pady 2 -row $i -column 1
grid .frAlles.c.frWidgets.bt$i -padx 2 -pady 2 -row $i -column 2
}
# create frame with buttons
ttk::frame .frAlles.c.frButtons -borderwidth 1 -relief solid -width 340 -height 40
ttk::button .frAlles.c.frButtons.btOK -text "OK" -command exit
ttk::button .frAlles.c.frButtons.btAbbruch -text "Abbruch" -command exit
pack .frAlles.c.frButtons.btOK -padx 2 -pady 2 -side left
pack .frAlles.c.frButtons.btAbbruch -padx 2 -pady 2 -side left
# place widgets and buttons
.frAlles.c create window 0 0 -anchor nw -window .frAlles.c.frWidgets
.frAlles.c create window 200 650 -anchor c -window .frAlles.c.frButtons
# determine the scrollregion
.frAlles.c configure -scrollregion [.frAlles.c bbox all]
# show the canvas
pack .frAlles -expand yes -fill both -side top
但是,如果我删除画布内的框架,以便我直接在画布内拥有小部件,则滚动不再起作用:我有滚动条,但它们没有效果。
你知道为什么吗?
这是修改后的代码,没有框架 frWidgets 和 frButtons。我删除了框架,因为第一个框架包含大量的检查按钮小部件,然后我无法为第二个框架执行创建窗口命令,因为第一个框架会很长。例如,如果循环不是 20 而是 200,则按钮将显示在列表前面,并且滚动条不会显示完整列表。它的作用就好像滚动条仅用于显示两个帧而不是第一帧的整体。 (很难解释,但代码可以轻松地在 Wish 命令中执行)
ttk::frame .frAlles
# create canvas with scrollbars
canvas .frAlles.c -width 400 -height 200 -xscrollcommand ".frAlles.xscroll set" -yscrollcommand ".frAlles.yscroll set"
ttk::scrollbar .frAlles.xscroll -orient horizontal -command ".frAlles.c xview"
ttk::scrollbar .frAlles.yscroll -command ".frAlles.c yview"
pack .frAlles.xscroll -side bottom -fill x
pack .frAlles.yscroll -side right -fill y
pack .frAlles.c -expand yes -fill both -side top
# create frame with widgets
for {set i 0} {$i <=20} {incr i} {
ttk::label .frAlles.c.lb$i -text "Label $i:"
ttk::entry .frAlles.c.en$i
ttk::button .frAlles.c.bt$i -text "Button $i" -command exit
grid .frAlles.c.lb$i -padx 2 -pady 2 -row $i -column 0
grid .frAlles.c.en$i -padx 2 -pady 2 -row $i -column 1
grid .frAlles.c.bt$i -padx 2 -pady 2 -row $i -column 2
}
ttk::button .frAlles.c.btOK -text "OK" -command exit
ttk::button .frAlles.c.btAbbruch -text "Abbruch" -command exit
pack .frAlles.c.btOK -padx 2 -pady 2 -side left
pack .frAlles.c.btAbbruch -padx 2 -pady 2 -side left
# determine the scrollregion
.frAlles.c configure -scrollregion [.frAlles.c bbox all]
# show the canvas
pack .frAlles -expand yes -fill both -side top
我还尝试了这个小代码,它创建了一个带有线条的画布,并且画布内部有很多检查按钮。滚动仅适用于画布和线条,但不适用于画布内的按钮:-(
package require Tk
proc scrolled w {
set pa [set pa0 [winfo parent $w]]
if {$pa eq "."} {set pa ""}
grid $w [scrollbar $pa.y -command "$w yview"] -sticky news
$w configure -xscrollcommand "$pa.x set" -yscrollcommand "$pa.y set"
grid $pa.y -sticky ns
grid [scrollbar $pa.x -ori hori -command "$w xview"] -sticky ew
grid columnconfigure $pa0 0 -weight 1
grid rowconfigure $pa0 0 -weight 1
for {set i 0} {$i <=200} {incr i} {
ttk::label .c.lb$i -text "Label $i:"
ttk::entry .c.en$i
ttk::button .c.bt$i -text "Button $i" -command exit
grid .c.lb$i -padx 2 -pady 2 -row $i -column 0
grid .c.en$i -padx 2 -pady 2 -row $i -column 1
grid .c.bt$i -padx 2 -pady 2 -row $i -column 2
}
}
canvas .c -background beige
.c create line 10 10 10000 10000
.c configure -scrollregion [.c bbox all]
scrolled .c
我尝试了你的最后一个例子并看到了你的问题。但你这样做的方式不起作用。画布是一种绘图元素,它不像框架那样容纳小部件。因此使用
pack
或 grid
不起作用。顺便说一句,您不应该在同一元素内混合使用 pack
和 grid
。
解决问题的方法是使用窗口项:
<canvas> create window x y ?option value ...?
或者摆脱画布...