2016-07-07 22 views
1

Ich möchte ein Fenster mit zwei Textfeldern übereinander erstellen, die zuerst 25% der Höhe einnehmen und dann 75% der Höhe einnehmen.Tcl/tk - Fensterhöhe und -breite abrufen und relative Texthöhe im Raster einstellen

Ich habe versucht, relative Höhe/Breite von Toplevel Win zu berechnen und Textbefehl übergeben, aber nicht funktioniert (ich rate, weil die Einheiten der Dimension von WM-Geometrie zurückgegeben ist nicht das gleiche wie bei Textbefehl übergeben)

Im Anschluss ist mein Code:

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 

Als ich folgenden versucht - es mir ein paar anständige GUI gab:

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 

aber ich mag die relati verwenden Optionen. Wie funktioniert es?

Antwort

2

Der einfachste Weg, dies zu lösen, ist die Verwendung des Grid Geometry Managers mit Gewichten im richtigen Verhältnis und einer einheitlichen Gruppe. Es wird sogar gut funktionieren, wenn Sie die Größe des Fensters ändern; Tk kennt die Richtlinie selbst und hält sie für Sie bereit. (Intern ist grid eine ziemlich anspruchsvolle Constraintlöser;. Sie können mit ihm einige wirklich komplizierte Dinge zu tun)

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 

(Wenn Sie mit Tk 8.5, werden Sie die Zeilen rowconfigure angeben müssen nach Nummer statt der oft mehr gelegen Namen eines Widgets in der Zeile.)

1

Ja, die -height und -width Optionen für das text Widget in Zeicheneinheiten gegeben sind, nicht Einheiten screenen. Sie können das beheben, indem Sie weiter nach Schriftbreite und -höhe dividieren (ich setze sie unten auf konstante Werte). Denken Sie daran, dass dies eine ganzzahlige Division ist!

Oooh, all diese Regexes ... Ich habe ein bisschen aufgeräumt, du kannst es nehmen oder es lassen.

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" 
     } 
    } 
} 

Auch verwendet man -width als Argument an topAspect sowohl für -height und -width: Ich nehme an, dass ein Fehler war.

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 

Ansonsten empfehle ich Donal Fellows Lösung.

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

+0

darauf geachtet werden muss, Geometrie Ausgabe Parsen wie es negative Offsets in Multimonitor-Setups haben. zB: '200x200 + -638 + 77' auf meiner. Also die 'scan' Anweisung, die korrekt analysiert wird, ist '[scan $ geometrie'% dx% d +% d +% d"] 'welche die Negative verarbeiten kann. – patthoyts

+0

Danke für die Korrektur, ich habe die Dokumentation des Formats missverstanden. Aber von meinem gegenwärtigen Verständnis könnte das Präfix - ebenso wie +, möglicherweise gefolgt vom Zeichen von g die Zahl sein. Wenn ja, müsste es mit '{% dx% d% * 1 [+ -]% d% * 1 [+ -]% d}' oder dem regulären Ausdruck '{(\ d +) x (\ d +) [+ -] ([+ -]? \ d +) [+ -] ([+ -]? \ d +)} '. –

+0

Das Format WxH-X + Y (mit einem führenden Minus für den X-Offset zeigt an, dass die Position vom rechten Ende des Bildschirms ist - Siehe die Kommentare zu WM_NEGATIVE_X in tkWinWm.c. So könnten wir möglicherweise 1x1- -2 + 3 "Ich denke ja. Sieht aus wie eine Regex ist notwendig. – patthoyts

0

Platz am besten funktioniert in diesem Fall - auch die Proportionen der folgenden hinhielt gut auf resizing:

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 

Gibt es eine Gefahr, dass jemand Gitter in diesem Ansatz sieht im Vergleich.

Danke

+0

Das Hauptproblem bei der Verwendung von 'place' besteht darin, dass es keine Größen an das enthaltende Widget weitergibt. Dies könnte für Sie von Bedeutung sein oder auch nicht, je nachdem, was im Rest Ihrer GUI vor sich geht. Sie können es auch beheben, indem Sie das Ereignis "" auf den rechten Widgets binden, aber das ist der Punkt, an dem die Dinge ziemlich kompliziert werden können. –

+0

Ok - ich werde mit Gittern arbeiten, wie Sie vorgeschlagen haben, und wenn es gut funktioniert, wird dasselbe verwendet - Danke nochmal – BabyGroot