To wit:
::ttk::setTheme default
::ttk::label .l -text "this is a label widget"
::ttk::labelframe .lf -text Hello -pad 10
message .lf.m -text "This is a message widget"
pack .l -side top -pady .2i
pack .lf -side top
pack .lf.m -side top
=> label widget has a different background from the toplevel
=> message widget has a diffent background from the labelframe
Long question:
I finally had a chance to view one of my tile aware
Windows apps on Linux and I must say it looked horrible.
My coded was tuned for xpnative and winnative, but using
clam, etc. exposed some problems. I fixed most of the
glitches but one remained which I don't know the best
way to fix.
Problem: background color of ::ttk::* widgets don't match
those of the ::tk::* widgets, so when you have a bunch
of, say, a tile label widgets in the main window, it
looks horrible because the backgrounds are mismatched.
Likewise, having a message widget (or canvas, text, etc)
inside a tile frame looks equally bad.
What's the proper way of handling this? Some ideas I've tried are
o . config -bg [lindex [. config -bg] 3]
-- for some reason the default value (not the actual value) of
non-tk widgets is very close (but not exactly right) to the
tile background
o get exact background with '::ttk::style configure TLabel -
background'
-- doesn't work, since -background seems to be inherited from
somewhere. Ref: http://groups.google.com/group/comp.lang.tcl/msg/9609eea917712b1b
Both attempts besides not working correctly, seem to violate the
whole theme gestalt.
Other tile nits I ran into:
* ::ttk::label default anchor and justify is different
from ::tk::label
* why can't we have -vcmd, -bg, -fg and -bd configuration
abbreviations?
* ::ttk::frame have no -height/-width option
* ::ttk::frame have only -pad not -padx/-pady
Keith
Have you considered creating a ttk::frame and packing it to fill the
toplevel, then putting all other widgets inside this frame?
Ugh, do people really do that? I can't be the first
person to face this problem.
Keith
Yes; it works so why make *another* widget? It doesn't need to make that
much difference to the names of the widgets you interact with though;
the -in option to the geometry managers lets you avoid that stuff.
Donal.
Another method is to create a frame and turn it into a toplevel:
ttk::frame .top
wm manage .top
wm deiconify .top
--Koen
> Ugh, do people really do that? I can't be the first
> person to face this problem.
I do. Nothing bad about that. Just store widget objects into variables and
you'll see no difference between ordinal toplevel and frame embedded in
toplevel.
Storing in variables (I think it's common developing routine) gives one more
big adventage - it's much easier to move/reparent widgets, because you have
to do this only in one place, instead of mass-replacing.
--
Pozdrawiam! (Regards!)
Googie
Looking at code in tk_library I see two approaches: tk_getOpenFile
shoves a frame inside the toplevel; tk_messageBox uses this code
snippet:
# There is only one background colour for the whole dialog
set bg [ttk::style lookup . -background]
...
toplevel $w -class Dialog -bg $bg
Keith
Generally there are numerous differences between Tk and TTk
(unfortunetly :( ). After some time of playing with Tile I've managed to get
applications look quiet nice - see SQLiteStudio (sqlitestudio.one.pl),
but...
Big problems come when you try to make [spinbox] look nice in Tile
application, or try to place ttk::checkbutton inside of canvas (as window
item - it has its own background, not applicable for canvas). I don't
really know how to handle these things :(
Good hint is to avoid placing tk widgets inside of ttk widgets. Best way is
to place ttk::frame in toplevel and build whole application using ttk::*
widgets. Yes, you have to use old tk::spinbox, but I've mentioned it
before.
Answering your other questions:
> Other tile nits I ran into:
> * ::ttk::label default anchor and justify is different
> from ::tk::label
Always use ttk::label, then the behaviour will be predictable.
Anchor and justify is controlled by style, not by widget option (like it was
in tk).
> * why can't we have -vcmd, -bg, -fg and -bd configuration
> abbreviations?
-fg, -bg, -bd - these are not aplicable for ttk model. Ttk uses styles to
configure widgets look, instead of options.
-vcmd - I agree, it should be here, but it's not a big loss, use [bind].
> * ::ttk::frame have no -height/-width option
> * ::ttk::frame have only -pad not -padx/-pady
Same as above, not applicable for ttk model.
--
Pozdrawiam! (Regards!)
Googie
I used to have the same opinion -- store widgets in variables. Then I
realized I can just put almost everything in "." and use the -in option
for pack and grid. I find this to be much easier in practice than to
deal with variables. I rarely if ever have any widgets that are more
than two deep.
tk_setPalette background [ttk::style lookup $currentTheme -background]
--
ZB
I used a message widget inside a labelframe
as my problem example. The solution I came
up with is:
canvas .c
.c config -bg [::ttk::style lookup . -background]
bind .c <<ThemeChanged>> \
{.c config -bg \[::ttk::style lookup . -background]}
> Answering your other questions:
>
> > Other tile nits I ran into:
> > * ::ttk::label default anchor and justify is different
> > from ::tk::label
>
> Anchor and justify is controlled
> by style, not by widget option
...
> -fg, -bg, -bd - these are not applicable
> for ttk model. Ttk uses styles to configure
> widgets look, instead of options.
Actually, -anchor, -justify, -foreground, -background,
and -borderwidth are legal widget options for
the ::ttk::label widget.
Now if you're saying that it's better practice to
set these via a new style, I might be tempted to
agree with you.
Keith
Do you realize that does _way_ more than just changing the background of
a toplevel widget? I would never recommend using tk_setPalette except
under the most unusual of circumstances.
>> tk_setPalette background [ttk::style lookup $currentTheme -background]
>
> Do you realize that does _way_ more than just changing the background of
> a toplevel widget?
Yes, it's changing background of all the widgets. Since some of the Tk
widgets doesn't have Ttk counterparts, it's a must, when you're changing the
theme.
> I would never recommend using tk_setPalette except
> under the most unusual of circumstances.
Works for me.
--
ZB
> Actually, -anchor, -justify, -foreground, -background,
> and -borderwidth are legal widget options for
> the ::ttk::label widget.
>
I didn't know that. I guess I'm not up to date with Tile.
...or you're saying that ttk::label accepts these options but do they apply
them? I think that they might be just for backward-compatibility, but do
not do any difference to look.
> Now if you're saying that it's better practice to
> set these via a new style, I might be tempted to
> agree with you.
Now - after reading above - I'm not so sure :)
--
Pozdrawiam! (Regards!)
Googie
> I used to have the same opinion -- store widgets in variables. Then I
> realized I can just put almost everything in "." and use the -in option
> for pack and grid. I find this to be much easier in practice than to
> deal with variables. I rarely if ever have any widgets that are more
> than two deep.
What about later management of these widget? For example it's good to have
canvas object in some variable, since you'll propably do many operations on
it later.
I'm not a big fan of putting every single widget into a variable, but ones
which are important for operations and for logical layout (reparenting,
etc).
--
Pozdrawiam! (Regards!)
Googie
Problem 1: ttk widgets placed in tk widgets, such
as a toplevel, have a background color different
from its container.
Example:
::ttk::setTheme default
pack [::ttk::label .l -text "Hello, world"] -padx 1i -pady 1i
Solutions:
1. shove a ttk::frame inside the toplevel -- this is what
tk_getOpenFile on Unix does
toplevel .top
pack [::ttk::frame .top.f] -fill both -expand 1
2. turn a ttk::frame into a toplevel -- very clever, requires 8.5
::ttk::frame .top
wm manage .top
wm deiconify .top
3. configure the non-tile widget's background correctly with -- this
is what tk_messageBox on Unix does
. configure -bg [::ttk::style lookup . -background]
4. configure all backgrounds correctly -- BIG hammer approach
since it sets much more than just the background
tk_setPalette background [::ttk::style lookup . -background]
Bug:
Solutions 3 & 4 will be incorrect if you change themes. You can fix
this with:
bind $w <<ThemeChanged>> "$w config -bg \[::ttk::style lookup . -
background]"
----
Problem 2: non-ttk widgets (message, spinbox) put inside ttk widgets
have a background color different from its container.
Example:
::ttk::setTheme default
pack [::ttk::labelframe .lf -text Hello -pad 10]
pack [message .lf.m -text "This is a message widget"]
Solution: see solutions 3 & 4 above (and bug fix)
Keith
> 2. turn a ttk::frame into a toplevel -- very clever, requires 8.5
>
> ::ttk::frame .top
> wm manage .top
> wm deiconify .top
No. You can currently only manage tk::frames. Not ttk::frames.
> 3. configure the non-tile widget's background correctly with -- this
> is what tk_messageBox on Unix does
>
> . configure -bg [::ttk::style lookup . -background]
No. There is no certainty that the background will even be a
colour. In a given theme it might be a gradient or a pixmap.
> 4. configure all backgrounds correctly -- BIG hammer approach
> since it sets much more than just the background
>
> tk_setPalette background [::ttk::style lookup . -background]
As above.
>Problem 2: non-ttk widgets (message, spinbox) put inside ttk widgets
>have a background color different from its container.
Spinbox needs doing as ttk::spinbox.
At the moment - put a ttk::frame in your toplevel and put everything
else into it.
--
Pat Thoyts http://www.patthoyts.tk/
To reply, rot13 the return address or read the X-Address header.
PGP fingerprint 2C 6E 98 07 2C 59 C8 97 10 CE 11 E6 04 E0 B9 DD
I use hard-coded widget paths. In your example, the canvas would be
named ".canvas". Anywhere I need to reference it I use ".canvas".
I tested this code on both 8.5.1 Windows and 8.5.2 Unix
before posting. Works ok for me.
> > 3. configure the non-tile widget's background correctly with -- this
> > is what tk_messageBox on Unix does
>
> > . configure -bg [::ttk::style lookup . -background]
>
> No. There is no certainty that the background will even be a
> colour. In a given theme it might be a gradient or a pixmap.
That code is copied from ActiveState 8.5.2 released code in
both msgbox.tcl and tkfbox.tcl.
> >Problem 2: non-ttk widgets (message, spinbox) put inside ttk widgets
> >have a background color different from its container.
>
> Spinbox needs doing as ttk::spinbox.
Then we also need ::ttk::message, ::ttk::canvas, etc.
Let me know when you've written them :)
Keith
Check out http://wiki.tcl.tk/11290
In fact, it was that very wiki page back in 2004 that got me to
reconsider how I write GUIs. I did a complete 180 and find that using
hard-coded, top-of-the-hierarchy widget paths to be much easier to write
and maintain.
> Then we also need ::ttk::message, ::ttk::canvas, etc.
> Let me know when you've written them :)
ttk::canvas is way too much. It's kind of special widget and it does not
contain any theme-related pieces. If you want to give it some theme-related
border you can just set it's border width to 0 and put it inside of
ttk::frame.
--
Pozdrawiam! (Regards!)
Googie
As the author of both snippets, I used the "get the background" style
for tk_messageBox because I also needed to make the background of a
canvas widget match; what I did won't work if a theme with a gradient
background is in use, but none of the standard X11 themes have this
particular issue. (The alternative would have been to have reworked the
icon images into real images, but I didn't have the time then. I'm also
not too good at graphic art...)
Donal.
>On May 14, 10:10 am, Pat Thoyts <cnggub...@hfref.fbheprsbetr.arg>
>wrote:
>> keithv <kvet...@gmail.com> writes:
>> > 2. turn a ttk::frame into a toplevel -- very clever, requires 8.5
>>
>> > ::ttk::frame .top
>> > wm manage .top
>> > wm deiconify .top
>>
>> No. You can currently only manage tk::frames. Not ttk::frames.
>
>I tested this code on both 8.5.1 Windows and 8.5.2 Unix
>before posting. Works ok for me.
Interesting. I tested this a bit harder and it appears to silently
fail when I [wm manage] a ttk::frame. However if I later [raise] the
managed frame it becomes visible.
>> > 3. configure the non-tile widget's background correctly with -- this
>> > is what tk_messageBox on Unix does
>>
>> > . configure -bg [::ttk::style lookup . -background]
>>
>> No. There is no certainty that the background will even be a
>> colour. In a given theme it might be a gradient or a pixmap.
>
>That code is copied from ActiveState 8.5.2 released code in
>both msgbox.tcl and tkfbox.tcl.
That doesn't mean its correct. It may work for now but it will be
fragile. The above should be deemed a bug in the Tk code in question.
>> >Problem 2: non-ttk widgets (message, spinbox) put inside ttk widgets
>> >have a background color different from its container.
>>
>> Spinbox needs doing as ttk::spinbox.
message is as I understand it deprecated. canvas doesn't need anything
except maybe picking up the current border from the theme. Same as the
text widget and in these cases I place then in a frame with right
border. The main text widget in Tk chat is an example of this framing
of a text widget. It makes more sense to remove the border entirely
from the canvas and text widgets as at least on windows when you place
a scrollbar next to them the visible border needs to go around the
pair of widgets. Listbox gets the same treatment in the tk_chooseFont
patch.
The problem with canvas is its background color.
Sometimes, like for Unix tk_messageBox, the canvas wants to blend
in with the rest of the window. (For tk_messageBox you could work
around it by using images in a label instead of drawings, but that
won't always work).
Other times, you want to put tile widgets onto the canvas. Actually
it may just only be ttk::label which is a problem in which case
you could just use the old label widget.
Keith