views:

544

answers:

4

I want to put a canvas with an image in my window, but then I want to pack() widgets over top of it so the canvas acts as a background. Is it possible to have two states for the pack() manager, one for one set of widgets and another for another set?

+2  A: 

The answer to your specific question is no. You can't have two states or otherwise use pack two different ways in the same parent.

However, what I think you want to accomplish is simple. Use the built-in features of the canvas to create an image item that is part of the canvas, then pack things into the canvas as if it were a frame.

You can accomplish a similar thing by creating a label widget with an image, then pack your other widgets into the label.

One advantage to using a canvas is you can easily tile an image to fill the whole canvas with a repeating background image so as the window grows the image will continue to fill the window (of course you can just use a sufficiently large original image...)

Bryan Oakley
I like your answer - you were absolutely correct about everything - except the whole approach turned out to be unworkable because I wanted to add labels and more canvases to it, but I can't find any way to make their backgrounds transparent. Do you happen to know of any way?
Matt Gregory
I don't understand the problem well enough to answer your question. It's not clear why you need to make anything transparent. For example, what's the point of adding a canvas to a canvas? There's a good chance what you want to accomplish is possible, just maybe not in the way you think.
Bryan Oakley
+1  A: 

I believe that Bryan's answer is probably the best general solution. However, you may also want to look at the place geometry manager. The place geometry manager lets you specify the exact size and position of the widget... which can get tedious quickly, but will get the job done.

erichui
A: 

Not without swapping widget trees in and out, which I don't think can be done cleanly with Tk. Other toolkits can do this a little more elegantly.

  • COM/VB/MFC can do this with an ActiveX control - you can hide/show multiple ActiveX controls in the same region. Any of the containers will let you do this by changing the child around. If you're doing a windows-specific program you may be able to accomplish it this way.
  • QT will also let you do this in a similar manner.
  • GTK is slightly harder.
ConcernedOfTunbridgeWells
I'm not sure what you mean by "swapping widget trees in and out". If by that you mean stacking widgets and raising or lowering widgets that occupy the same space, Tk can do that trivially. Perhaps that's not what you mean though.
Bryan Oakley
Changing the child of a container widget and hiding/disabling the old child.
ConcernedOfTunbridgeWells
You can certainly have multiple children in a container and hiding all but one. There are at least two supported ways to do that - raise/lower or use the geometry manager to forget one and add another. grid is particularly good at this (read up on "grid remove")
Bryan Oakley
+1  A: 

... turned out to be unworkable because I wanted to add labels and more canvases to it, but I can't find any way to make their backgrounds transparent

If it is acceptable to load an additional extension, take a look at Tkzinc. From the web site,

Tkzinc (historically called Zinc) widget is very similar to the Tk Canvas in that they both support structured graphics. Like the Canvas, Tkzinc implements items used to display graphical entities. Those items can be manipulated and bindings can be associated with them to implement interaction behaviors. But unlike the Canvas, Tkzinc can structure the items in a hierarchy, has support for scaling and rotation, clipping can be set for sub-trees of the item hierarchy, supports muti-contour curves. It also provides advanced rendering with the help of OpenGL, such as color gradient, antialiasing, transparencies and a triangles item.

I'm currently using it on a tcl project and am quite pleased with the results. Extensions for tcl, perl, and python are available.

erichui
I'm just working on a school assignment right now, but I would definitely consider it for something serious. Thanks for the tip!
Matt Gregory