Tcl/tk - 获取 window 高度和宽度并设置网格中的相对文本高度

Tcl/tk - Get window height and width and set relative text height in grid

我想创建一个 window,其中有两个文本框,一个位于另一个之上,第一个占高度的 25%,下一个占高度的 75%。

我试图计算相对 height/width 的顶层胜利并传递到文本命令但没有成功(我猜是因为 wm geometry 返回的尺寸单位与传递到文本时不同命令)

以下是我的代码:

toplevel .t
wm geometry .t 1500x800+10+10
update
proc topAspect {args} {
    regexp {(\d+)} $args -> relAspect
    regexp {([^\d|%]+)} $args -> aspect
    regexp {(.*)x(.*)[+-](.*)[+-](.*)} [wm geometry .t] -> width height x y
    puts "width->$width height->$height x->$x y->$y"
    switch -regexp [string tolower $aspect] {
        x {
            return [expr $x + $relAspect]
        }
        y {
            return [expr $y + $relAspect]
        }
        w {
            return [expr $width * $relAspect / 100]
        }
        h {
            return [expr $height * $relAspect / 100]
        }
        default {
            log::log error "Unsupported relative aspect $aspect cannot be determined for top level window"
        }
    }
}

text  .t.text1 -height [topAspect -width 25%] -width [topAspect -width 99%]
grid .t.text1 -sticky news
text  .t.text2 -height [topAspect -width 75%] -width [topAspect -width 99%]
grid .t.text2 -sticky news

当我尝试跟随 - 它确实给了我一些不错的 GUI:

text  .t.text1 -height 20 -width [topAspect -width 99%]
grid .t.text1 -sticky news
text  .t.text2 -height 20 -width [topAspect -width 99%]
grid .t.text2 -sticky news

但我想使用相对选项。如何让它发挥作用?

解决这个问题的最简单方法是使用具有正确比例权重和统一组的网格几何管理器。当您调整 window 的大小时,它甚至可以正常工作; Tk 了解政策本身并为您维护。 (在内部,grid 是一个相当复杂的约束求解器;您可以用它做一些 真正 复杂的事情。)

toplevel .t
grid [text .t.text1 -bg red]   -sticky news
grid [text .t.text2 -bg green] -sticky news

# The group name is just an arbitrary non-empty string.
# So long as it is the same on the two rows it will work as desired.
# The weights give a ratio of 1:3, i.e., 25% to one and 75% to the other.

grid rowconfigure .t .t.text1 -weight 1 -uniform group1
grid rowconfigure .t .t.text2 -weight 3 -uniform group1

(如果您使用的是 Tk 8.5,则需要将行指定为 rowconfigure 按编号而不是行中小部件的通常更方便的名称。)

是的,text 小部件的 -height-width 选项以字符单位而非屏幕单位给出。您可以通过进一步除以字体宽度和高度来解决这个问题(我将它们设置为下面的常量值)。记住这是整数除法!

哦,所有那些正则表达式……我已经清理了一点,你可以接受也可以不接受。

proc topAspect {aspect relAspect} {
    set relAspect [string trimright $relAspect %]
    scan [wm geometry .t] "%dx%d%d%d" width height x y
    set fontWidth 15
    set fontHeight 15
    switch -regexp [string tolower $aspect] {
        x {
            return [expr {$x + $relAspect}]
        }
        y {
            return [expr {$y + $relAspect}]
        }
        w {
            return [expr {($width * $relAspect / 100) / $fontWidth}]
        }
        h {
            return [expr {($height * $relAspect / 100) / $fontHeight}]
        }
        default {
            log::log error "Unsupported relative aspect $aspect cannot be determined for top level window"
        }
    }
}

此外,对于 -height-width,您使用 -width 作为 topAspect 的参数:我认为这是一个错误。

text  .t.text1 -height [topAspect -height 25%] -width [topAspect -width 99%]
grid .t.text1 -sticky news
text  .t.text2 -height [topAspect -height 75%] -width [topAspect -width 99%]
grid .t.text2 -sticky news

否则,我推荐 Donal Fellows 的解决方案。

文档: * (operator), + (operator), / (operator), expr, for, grid, proc, return, scan, set, string, switch, text (widget), wm, Syntax of Tcl regular expressions

Place 在这种情况下效果最好 - 即使在调整以下尺寸时也能很好地保持比例:

place .t.text1  -in .t -relheight .25 -relwidth .98 -relx .003 -rely .003
place .t.text2 -in .t -relheight .75 -relwidth .98 -relx .003 -rely .254

与网格相比,这种方法是否存在任何缺陷。

谢谢