我组装Tk窗口的方式有问题(使用R tcltk和tcltk2,在Win XP下)
library(tcltk)
library(tcltk2)
expandTk <- function() {
root <- tktoplevel()
# textbox with scroll bars
textbox <- tk2frame(root)
scr <- tkscrollbar(textbox, repeatinterval=5, command=function(...) tkyview(txt,...))
txt <- tktext(textbox, bg="white", font="courier", wrap="word", yscrollcommand=function(...)tkset(scr,...))
tkpack(txt, side="left", fill="both", expand=TRUE)
tkpack(scr, side="right", fill="y")
tkmark.set(txt,"insert","0.0")
tkpack(textbox, fill="both", expand=TRUE)
# status bar and size grip
statusText <- tclVar("")
f <- tk2frame(root, relief="sunken")
l <- tk2label(f, textvariable=statusText)
tkpack(l, side="left", pady=2, padx=5, expand=0, fill="x")
tkpack(f, side="left", expand=1, fill="x", anchor="s")
sg <- ttksizegrip(root)
tkpack(sg, side="left", expand=0, anchor="se")
}
这个窗口看起来不错,但我一调整它的大小(即缩小它),滚动条和状态栏就消失了。我很确定这是一个用户错误,我看到其他Tk应用程序可以正确调整大小,但我不知道我应该使用哪个选项。。。
感谢任何提示,Karsten
这是Tk pack
几何图形管理器的标准行为。以下是pack
手册页的相关部分:
如果空腔变得太小,无法满足从属设备的需求,则奴隶将得到空腔中剩余的任何空间。如果空腔收缩如果大小为零,则装箱单上的所有剩余从属设备将从直到主窗口变得足够大以再次容纳它们。
因此,如果您将整个窗口缩小到小于文本小部件所需的空间,则不会为其他小部件留出空间,它们就会被取消映射。
最好的解决方案是使用grid
几何图形管理器,而不是pack
。总的来说,我发现grid
比pack
更容易使用和使用,尽管你的里程可能会有所不同。特别是,它消除了对许多多余的框架小部件的需要,这可以大大简化代码。
我想你可以用这样的东西:
expandTk <- function() {
root <- tktoplevel()
# textbox with scroll bars
textbox <- tk2frame(root)
txt <- tktext(textbox, bg="white", font="courier", wrap="word", yscrollcommand=function(...)tkset(scr,...))
scr <- tkscrollbar(textbox, repeatinterval=5, command=function(...) tkyview(txt,...))
tkmark.set(txt,"insert","0.0")
# Set up the geometry for the stuff inside the "textbox" frame.
# The text and scrollbar widgets live on the same row.
tkgrid(txt, scr)
# The text widget should stick to all four sides of its parcel.
tkgrid.configure(txt, sticky="nsew")
# The scrollbar should stick to the top and bottom of its parcel, it need not stick to the
# left and right.
tkgrid.configure(scr, sticky="ns")
# When the window is resized, we want surplus space to be allocated to the text widget,
# which is in the top left corner of this frame.
tkgrid.columnconfigure(textbox,0,weight=1)
tkgrid.rowconfigure(textbox,0,weight=1)
# status bar and size grip
statusText <- tclVar("")
l <- tk2label(root, textvariable=statusText,relief="sunken")
sg <- ttksizegrip(root)
# Set up the geometry for the stuff inside the "root" window.
# First row is just the textbox frame...
tkgrid(textbox)
# Second row is the status label and the resize gadget
tkgrid(l, sg)
# The textbox widget should span 2 colums, and stick to all four sides of its parcel.
tkgrid.configure(textbox,columnspan=2,sticky="nsew")
# The status label should stick to all four sides of its parcel too
tkgrid.configure(l,sticky="nsew")
# The resize gadget should only stick to the bottom right of its parcel
tkgrid.configure(sg,sticky="se")
# When the window is resized, we want surplus space to go to the textbox frame (and from there
# to the text widget itself, which it will do thanks to the grid weights we set up above). The
# textbox frame is in the top left corner of its parent window.
tkgrid.columnconfigure(root,0,weight=1)
tkgrid.rowconfigure(root,0,weight=1)
}
这里有一些关于使用R中的grid
几何图形管理器的更多信息。
如果你坚持打包小部件,你应该意识到,如果没有足够的空间给所有小部件他们要求的空间,那么空间会优先给打包的第一个小部件(在特定容器内)。先放入状态栏,然后放入滚动条,然后再放入主窗口小部件。(你可能需要改变你将特定的小部件包装在哪一边,以使其正常工作。)此外,如果它变得太复杂,请记住,你可以将内部框架包装在内部框架中;这给了您很大的灵活性。
但这正是使用栅格几何图形管理器的意义所在。当你想要获得应用程序最后10%的外观时,它会给你更多的精细控制,并且需要更少的小部件嵌套来实现。
将此添加到代码末尾:
widthOfChar <- ceiling(as.numeric(tclvalue(tcl("font","measure","TkTextFont","0123456789")))/10) + 2
tkbind(root, "<Configure>", function(W) {
w.width <- as.integer(tkwinfo("width",W))
txt.width <- w.width - 15L
tkconfigure(txt, width=floor(txt.width/widthOfChar))
})