Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tile and toplevel background color

135 views
Skip to first unread message

keithv

unread,
May 12, 2008, 8:18:27 PM5/12/08
to
Short question: how do I get toplevel widgets
background to match that used by tile?

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

Bryan Oakley

unread,
May 12, 2008, 11:01:55 PM5/12/08
to
keithv wrote:
> Short question: how do I get toplevel widgets
> background to match that used by tile?

Have you considered creating a ttk::frame and packing it to fill the
toplevel, then putting all other widgets inside this frame?

keithv

unread,
May 13, 2008, 7:48:38 AM5/13/08
to

Ugh, do people really do that? I can't be the first
person to face this problem.

Keith

Donal K. Fellows

unread,
May 13, 2008, 8:19:29 AM5/13/08
to
keithv wrote:
> Ugh, do people really do that?

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.

Koen Danckaert

unread,
May 13, 2008, 8:49:46 AM5/13/08
to

Another method is to create a frame and turn it into a toplevel:

ttk::frame .top
wm manage .top
wm deiconify .top

--Koen

Googie

unread,
May 13, 2008, 9:59:14 AM5/13/08
to
keithv wrote:

> 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

keithv

unread,
May 13, 2008, 10:10:50 AM5/13/08
to
On May 13, 8:19 am, "Donal K. Fellows"

<donal.k.fell...@manchester.ac.uk> wrote:
> keithv wrote:
> > Ugh, do people really do that?
>
> Yes; it works so why make *another* widget?

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

Googie

unread,
May 13, 2008, 10:16:03 AM5/13/08
to
keithv wrote:
[...]

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

Bryan Oakley

unread,
May 13, 2008, 11:06:46 AM5/13/08
to

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.

ZB

unread,
May 13, 2008, 11:17:26 AM5/13/08
to
Dnia 13.05.2008 keithv <kve...@gmail.com> napisał/a:
> Short question: how do I get toplevel widgets
> background to match that used by tile?

tk_setPalette background [ttk::style lookup $currentTheme -background]
--
ZB

keithv

unread,
May 13, 2008, 11:47:04 AM5/13/08
to
On May 13, 10:16 am, Googie <n...@spam.0rg> wrote:
> Big problems come when you try to make [spinbox]
> look nice in Tile application, or try to place
> ttk::checkbutton inside of canvas

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

Bryan Oakley

unread,
May 13, 2008, 12:22:47 PM5/13/08
to

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.

ZB

unread,
May 13, 2008, 12:54:29 PM5/13/08
to
Dnia 13.05.2008 Bryan Oakley <oak...@bardo.clearlight.com> napisał/a:

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

USCode

unread,
May 13, 2008, 2:30:46 PM5/13/08
to
Googie wrote:
> 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 :(
>
Enter a bug/enhancement report for Joe in SourceForge so any issues you
encounter are at least on his radar. I suspect he's already aware of
the ones you mentioned but you might double-check in SF.

Googie

unread,
May 14, 2008, 2:57:19 AM5/14/08
to
keithv wrote:

> 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

Googie

unread,
May 14, 2008, 3:01:20 AM5/14/08
to
Bryan Oakley wrote:

> 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

keithv

unread,
May 14, 2008, 9:27:14 AM5/14/08
to
Here's a summary of solutions to the problems
I raised of mixing tile and non-tile widgets.

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

Pat Thoyts

unread,
May 14, 2008, 10:10:08 AM5/14/08
to
keithv <kve...@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.

> 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

Bryan Oakley

unread,
May 14, 2008, 11:00:57 AM5/14/08
to

I use hard-coded widget paths. In your example, the canvas would be
named ".canvas". Anywhere I need to reference it I use ".canvas".

keithv

unread,
May 14, 2008, 11:23:49 AM5/14/08
to
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.

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

keithv

unread,
May 14, 2008, 11:28:41 AM5/14/08
to

Bryan Oakley

unread,
May 14, 2008, 12:52:31 PM5/14/08
to

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.

Message has been deleted

Googie

unread,
May 15, 2008, 5:47:30 AM5/15/08
to
keithv wrote:

> 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

Donal K. Fellows

unread,
May 15, 2008, 6:27:54 AM5/15/08
to
keithv wrote:
> 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

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.

Pat Thoyts

unread,
May 15, 2008, 8:25:30 AM5/15/08
to
keithv <kve...@gmail.com> writes:

>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.

keithv

unread,
May 15, 2008, 10:13:01 AM5/15/08
to
On May 15, 8:25 am, Pat Thoyts <cnggub...@hfref.fbheprsbetr.arg>
wrote:
>

> message is as I understand it deprecated. canvas doesn't need anything
> except maybe picking up the current border from the theme.

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

0 new messages