🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.tcl
13 messages
13 total messages Started by Maciej Sobczak Thu, 28 Jul 2005 08:14
Tk - centrowanie głównego okna
#147
Author: Maciej Sobczak
Date: Thu, 28 Jul 2005 08:14
16 lines
1389 bytes
Poddaję się.

Czy ktoś z grupowiczów zna metodę na to, żeby główne okno programu 
Tcl/Tk ustawić na środku ekranu?

Mam drobny programik w Tcl/Tk, który jest uruchamiany przez inną 
aplikację okienkową. Jedyne okno tego drobnego pomocniczego programu 
wyświetla się w lewym górnym rogu ekranu - chciałbym, żeby pojawiło się 
na środku.

Bardziej ogólnie: chciałbym, żeby pojawiło się w zadanych (X, Y).


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/
Re: Tk - centrowanie głównego okna
#148
Author: kokoryn
Date: Thu, 28 Jul 2005 09:29
22 lines
1667 bytes
On Thu, 28 Jul 2005 10:14:09 +0200, Maciej Sobczak
<no.spam@no.spam.com> wrote:

> Poddaję się.
> 
> Czy ktoś z grupowiczów zna metodę na to, żeby główne okno programu 
> Tcl/Tk ustawić na środku ekranu?
> 
> Mam drobny programik w Tcl/Tk, który jest uruchamiany przez inną 
> aplikację okienkową. Jedyne okno tego drobnego pomocniczego programu 
> wyświetla się w lewym górnym rogu ekranu - chciałbym, żeby pojawiło się 
> na środku.
> 
> Bardziej ogólnie: chciałbym, żeby pojawiło się w zadanych (X, Y).

wm geometry ??

Jako pierwszy argument podajesz widget, a jako drugi string
określający kształt i położenie okna w formacie "widthxheight+x+y",
gdzie width i height to rozmiar, a x i y położenie względem lewej i
górnej krawędzi ekranu, jeśli dasz minusy zamiast plusów będze się
liczyć odpowiednio od prawej i dolnej krawędzi.
Re: Tk - centrowanie głównego okna
#149
Author: Maciej Sobczak
Date: Thu, 28 Jul 2005 12:55
27 lines
2071 bytes
kokoryn wrote:

> wm geometry ??
> 
> Jako pierwszy argument podajesz widget, a jako drugi string
> określający kształt i położenie okna w formacie "widthxheight+x+y",

Dzięki, zadziałało. Niestety, nadal mam problem.

Chciałbym w tym ustawieniu uwzględnić bieżący rozmiar okna (ten, który 
wynika z naturalnego rozmiaru jego elementów), który zależy od 
wyświetlanych w nim danych - a to jest znane w czasie wykonania.

Niestety, ten "naturalny" rozmiar okna jest znany dopiero wtedy, gdy 
okno się pojawi na ekranie - a ja chcę je ustawić na środku *zanim* się 
pojawi. Chodzi o to, że w tym czasie główna aplikacja czeka i się nie 
odświeża - wyświetlenie okna Tcl/Tk w jakimkolwiek miejscu i 
przesunięcie go odsłania część okna głównej aplikacji i tak odsłonięta 
część brzydko wygląda.

Czy jest jakaś metoda na poznanie naturalnego rozmiaru okna (tego, który 
wynika z upakowania jego elementów) przed jego pojawieniem się na ekranie?


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/
Re: Tk - centrowanie głównego okna
#150
Author: kokoryn
Date: Thu, 28 Jul 2005 14:41
31 lines
2140 bytes
On Thu, 28 Jul 2005 14:55:52 +0200, Maciej Sobczak
<no.spam@no.spam.com> wrote:

> Czy jest jakaś metoda na poznanie naturalnego rozmiaru okna (tego, który 
> wynika z upakowania jego elementów) przed jego pojawieniem się na ekranie?

Rozmiar, który wynika z upakowania elementów na oknie, jest zwracany
przez procedury:

winfo reqwidth
winfo reqheight

Natomiast nie wiem, czy da się te informacje uzyskać zanim okno
zostanie wyświetlone. Zajrzałem do Welcha i jest tam takie zdanie:

"A window's size is not set until a geometry manager maps a window
onto the display."

Z drugiej strony w dokumentacji obu tych procedur jest napisane:

"This is the value used by window's geometry manager to compute its
geometry."

Te stwierdzenia stoją w sprzeczności (choć może to wynikać z faktu, że
Welch pisał o którejś z wczesnych wersji 8.4, a dokumentacja jest dla
8.5), ale zdaje się, że Welch jednak ma rację, bo po małym sprawdzeniu
zauważyłem, że te procedury zawsze zwracają mi 200 przed wyświetleniem
okna, a prawidłową wartość dopiero po wyświetleniu. Inna rzecz, że
zawsze traktowałbym dokumentację jako nadrzędne źródło wobec choćby
najlepszej książki. Jest to dość zaskakująca sytuacja - nie wiem o co
tu chodzi.
Re: Tk - centrowanie głównego okna
#155
Author: Wojciech Kocjan
Date: Thu, 28 Jul 2005 17:04
27 lines
1721 bytes
Maciej Sobczak napisał(a):
> Poddaję się.
> 
> Czy ktoś z grupowiczów zna metodę na to, żeby główne okno programu 
> Tcl/Tk ustawić na środku ekranu?
> 
> Mam drobny programik w Tcl/Tk, który jest uruchamiany przez inną 
> aplikację okienkową. Jedyne okno tego drobnego pomocniczego programu 
> wyświetla się w lewym górnym rogu ekranu - chciałbym, żeby pojawiło się 
> na środku.
> 
> Bardziej ogólnie: chciałbym, żeby pojawiło się w zadanych (X, Y).

pod koniec:

# (bez tej linijki wszystko nie zadziala)
update idletasks

set width [winfo width .]
set height [winfo height .]
set swidth [winfo screenwidth .]
set sheight [winfo screenheight .]

wm geometry . +[expr {($swidth-$width)/2}]+[expr {($sheight+$height)/2}]

-- 
WK
Re: Tk - centrowanie głównego okna
#151
Author: Wojciech Kocjan
Date: Thu, 28 Jul 2005 17:09
43 lines
2742 bytes
kokoryn napisał(a):
> On Thu, 28 Jul 2005 14:55:52 +0200, Maciej Sobczak
> <no.spam@no.spam.com> wrote:
> 
> 
>>Czy jest jakaś metoda na poznanie naturalnego rozmiaru okna (tego, który 
>>wynika z upakowania jego elementów) przed jego pojawieniem się na ekranie?
> 
> 
> Rozmiar, który wynika z upakowania elementów na oknie, jest zwracany
> przez procedury:
> 
> winfo reqwidth
> winfo reqheight
> 
> Natomiast nie wiem, czy da się te informacje uzyskać zanim okno
> zostanie wyświetlone. Zajrzałem do Welcha i jest tam takie zdanie:
> 
> "A window's size is not set until a geometry manager maps a window
> onto the display."

Tak. To idzie w górę.

Na przykład jeśli mamy . i w nim .frame, to reqwidth/reqheight idzie 
dalej - czyli teoretycznie jeśli nie ma innej opcji to można zdublować 
geometry managera i pytać od najgłebszego obiektu wzwyż. No ale to 
oczywiście żmudne i bezcelowe.

> Te stwierdzenia stoją w sprzeczności (choć może to wynikać z faktu, że
> Welch pisał o którejś z wczesnych wersji 8.4, a dokumentacja jest dla
> 8.5), ale zdaje się, że Welch jednak ma rację, bo po małym sprawdzeniu
> zauważyłem, że te procedury zawsze zwracają mi 200 przed wyświetleniem
> okna, a prawidłową wartość dopiero po wyświetleniu. Inna rzecz, że
> zawsze traktowałbym dokumentację jako nadrzędne źródło wobec choćby
> najlepszej książki. Jest to dość zaskakująca sytuacja - nie wiem o co
> tu chodzi.

Nie. To ma całkowity sens. W każdej chwili możesz spytać o każdy 
najniżej osadzony widget. Gorzej z np frame, który jeszcze nie był 
przeliczony.

-- 
WK
Re: Tk - centrowanie głównego okna
#152
Author: kokoryn
Date: Thu, 28 Jul 2005 18:32
19 lines
1961 bytes
On Thu, 28 Jul 2005 19:09:08 +0200, Wojciech Kocjan
<hceicjow.backward@kocjan.org> wrote:

> Na przykład jeśli mamy . i w nim .frame, to reqwidth/reqheight idzie 
> dalej - czyli teoretycznie jeśli nie ma innej opcji to można zdublować 
> geometry managera i pytać od najgłebszego obiektu wzwyż. No ale to 
> oczywiście żmudne i bezcelowe.
[...]
> Nie. To ma całkowity sens. W każdej chwili możesz spytać o każdy 
> najniżej osadzony widget. Gorzej z np frame, który jeszcze nie był 
> przeliczony.

Tak, już zaczynam pojmować. Przeleciałem po wszystkich widgetach (od
"najgłębszych" do tych najbardziej "na wierzchu") i faktycznie
wszystkie nie-frame'y zwróciły konkretne wartości, frame'y 1x1, a okno
główne 200 i 200. Rozumiem, że te jedynki wynikają z tego, że wymiary
dla frame'a są obliczane w momencie, kiedy jest on upakowany? A da się
je przeliczyć zanim zostanie wyświetlony? I dlaczego dla okna toplevel
dostaję 200x200 (wygląda na jakąś wartość wziętą z sufitu)?
Re: Tk - centrowanie głównego okna
#153
Author: kokoryn
Date: Thu, 28 Jul 2005 18:35
9 lines
1319 bytes
On Thu, 28 Jul 2005 20:32:35 +0200, kokoryn <kokoryn_NO_SPAM_@o2.pl>
wrote:

> Tak, już zaczynam pojmować. Przeleciałem po wszystkich widgetach

Małe sprostowanie, żeby nie było wątpliwości - tu mi wypadł kawałek
zdania: "w prostym, przykładowym programie".

> (od "najgłębszych" do tych najbardziej "na wierzchu") i faktycznie
Re: Tk - centrowanie głównego okna
#154
Author: Wojciech Kocjan
Date: Fri, 29 Jul 2005 06:53
30 lines
2287 bytes
kokoryn napisał(a):
> Tak, już zaczynam pojmować. Przeleciałem po wszystkich widgetach (od
> "najgłębszych" do tych najbardziej "na wierzchu") i faktycznie
> wszystkie nie-frame'y zwróciły konkretne wartości, frame'y 1x1, a okno
> główne 200 i 200. Rozumiem, że te jedynki wynikają z tego, że wymiary
> dla frame'a są obliczane w momencie, kiedy jest on upakowany? A da się
> je przeliczyć zanim zostanie wyświetlony?

SYNOPSIS
update ?idletasks?

DESCRIPTION
This command is used to bring the application ``up to date'' by entering 
the event loop repeatedly until all pending events (including idle 
callbacks) have been processed.

If the idletasks keyword is specified as an argument to the command, 
then no new events or errors are processed; only idle callbacks are 
invoked. This causes operations that are normally deferred, such as 
display updates and window layout calculations, to be performed immediately.

Juz pisalem chyba o tym ;-)

> I dlaczego dla okna toplevel
> dostaję 200x200 (wygląda na jakąś wartość wziętą z sufitu)?

Chyba tak. Nie znam na wszystko odpowiedzi ;-)

-- 
WK
Re: Tk - centrowanie głównego okna
#156
Author: Googie
Date: Fri, 29 Jul 2005 09:26
51 lines
2431 bytes
Tu masz 2 procedury, ktore pewnie Ci sie przydadza:

#---------------------

proc center {path} {
 update
 set wd [winfo width $path]
 set ht [winfo height $path]
 set x [expr {([winfo screenwidth $path]-$wd)/2}]
 set y [expr {([winfo screenheight $path]-$ht)/2}]
 wm geometry $path +$x+$y
}

proc centerBy {path {parent {}}} {
 update
 if {$parent == ""} {
  set sp [split $path .]
  if {[llength $sp] > 2} {
   set parent [join [lrange $sp 0 end-1] .]
  } else {
   set parent .
  }
 }
 set sp [split [wm geometry $parent] +]
 set px [lindex $sp 1]
 set py [lindex $sp 2]
 set wd [winfo width $path]
 set ht [winfo height $path]
 set x [expr {$px+([winfo width $parent]-$wd)/2}]
 set y [expr {$py+([winfo height $parent]-$ht)/2}]
 wm geometry $path +$x+$y
}

#----------------

Pierwsza centruje okno na srodku pulpitu. Jako argument podaje sie
sciezke/nazwe okna.
Druga centruje okno na srodku danego okna. Jako drugi argument podaje się to
okno. Jesli jednak drugi argument zostanie pominiety, to okno zostanie
wycentrowane względem głownego okna aplikacji Tcl.

Jest jedna wada: okna musza sie pokazac, zanim zostana ustawione w
odpowiednim miejscu (za co odpowiada komenda [update] na poczatku kazdej z
procedur). Jest to spowodowane tym, ze window manager potrafi okreslic
wymiary okien dopiero po ich pokazaniu, a wymiary te sa potrzebne do
wycentrowania. Podejrzewam, ze da sie ten problem ominac uzywajac [wm
withdraw], trzeba pokombinowac :)

--
Pozdrawiam!
Googie
Re: Tk - centrowanie g³ównego okna
#157
Author: Maciej Sobczak
Date: Mon, 08 Aug 2005 07:41
31 lines
2286 bytes
Googie wrote:
> Tu masz 2 procedury, ktore pewnie Ci sie przydadza:
[...]

> Jest jedna wada: okna musza sie pokazac, zanim zostana ustawione w
> odpowiednim miejscu (za co odpowiada komenda [update] na poczatku kazdej z
> procedur).

I to jest właśnie problem. W moim przypadku okno programu Tcl/Tk 
pokazuje się na skutek wywołania ze strony innej aplikacji, która jest 
zablokowana do czasu zakończenia programu Tcl. Po wykonaniu [update] ta 
większa aplikacja zostaje zasłonięta, natomiast po wykonaniu [wm 
geometry] okno Tcl przesunie się odsłaniają część większej aplikacji, 
ale ponieważ ta większa aplikacja jest zablokowana czekając na 
zakończenie programu Tcl, to się też nie odświeża - w efekcie powstaje 
brzydki obszar pokazujązy gdzie było okno Tcl pomiędzy wywołaniami 
[update] i [wm geometry].

To, czego mi brakuje to możliwość wyznaczania naturalnego rozmiaru okna 
bez konieczności jego rysowania.

> Podejrzewam, ze da sie ten problem ominac uzywajac [wm
> withdraw]

Podejrzewam, że nie w tym przypadku - główna aplikacja jest zablokowana 
i się i tak nie odświeży, niezależnie od tricków po stronie Tcl.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/
Re: Tk - centrowanie g?ównego okna
#158
Author: Googie
Date: Mon, 08 Aug 2005 19:03
20 lines
1647 bytes
Maciej Sobczak wrote:

> To, czego mi brakuje to możliwość wyznaczania naturalnego rozmiaru
> okna bez konieczności jego rysowania.

Jeśli okna są zaprojektowane "raz, na zawsze", to można pokusić się o
uruchomienie aplikacji, wykonać [update] na danym oknie, następnie
sczytać jego rozmiary i położenie (zwyczajnie, przez: [wm
geometry .okno]), a następnie podstawić te dane jako argument przy
każdorazowym tworzeniu tego okna tak, aby współrzędne te zostały
ustawione, zanim okno się narysuje, czyli najlepiej tuż po wywołaniu
[toplevel] dla tego okna.

Tym sposobem okno pojawi się od razu na swoim miejscu i w odpowiednim
rozmiarze. Wadą jest to, że musisz na sztywno wpisać
rozmiary/położenie okna.

-- 
Pozdrawiam (Greetings)!
Googie
Re: Tk - centrowanie g³ównego okna
#159
Author: Wojciech Kocjan
Date: Tue, 09 Aug 2005 07:14
30 lines
1714 bytes
Maciej Sobczak napisał(a):
>> Podejrzewam, ze da sie ten problem ominac uzywajac [wm
>> withdraw]
> Podejrzewam, że nie w tym przypadku - główna aplikacja jest zablokowana 
> i się i tak nie odświeży, niezależnie od tricków po stronie Tcl.

A może:

proc centerWindow {p} {
     set xx [expr {([winfo screenwidth $p] - [winfo width $p]) / 2}]
     set xy [expr {([winfo screenheight $p] - [winfo height $p]) / 2}]

     wm geometry $p +${xx}+${xy}
}

toplevel .xx
frame .xx.yy
text .xx.yy.zz -width 100 -height 1
pack .xx.yy.zz -fill both -expand 1
pack .xx.yy -fill both -expand 1

wm withdraw .xx
update
centerWindow .xx
wm deiconify .xx

U mnie na Windows działa.

-- 
WK
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads