11
root = Tk()

descriptionFrame = Frame(root)

definitionFrame = LabelFrame(descriptionFrame, text="Definition")
definitionScroll = Scrollbar(definitionFrame)
definitionCanvas = Canvas(definitionFrame, width=30, height=4, yscrollcommand=definitionScroll.set)
definitionScroll.config(command=definitionCanvas.yview)
definitionLabel = Label(definitionCanvas, text="n/a")

descriptionFrame.pack()
definitionFrame.pack()
definitionScroll.pack(side=RIGHT, fill=Y)
definitionCanvas.pack(side=LEFT, fill=BOTH, expand=True)
definitionLabel.pack(fill=BOTH, expand=True)

root.mainloop()

I have this code. The Canvas is set to have a width of 30 and height of 4, but when I run this, it ignores the width and height of the Canvas and the resulting window is sized around the Label instead. I've tried using pack_propagate(False) on every single Frame in the code, but it doesn't affect anything for the definitionFrame, but when I use it on descriptionFrame it results in an empty window. How would I create a GUI where all the frames and the window are sized to the Canvas size of width 30 and height 4?

Thanks.

2
  • What sort of result are you aiming for? Adding a Label with a parent of a Canvas seems very unusual -- Canvas is for drawing charts and such, and the normal way to draw things on it is Canvas.create_(text|rectangle|widget|etc) Commented Oct 7, 2011 at 8:45
  • @Shish I was hoping to have a label inside the definitionFrame. Ideally I'd want the definitionFrame to be width 30 and height 4, with the label changing size according to however long the definition string is. But in that case I'd need a scrollbar for whenever a string is too long for a width 30 and height 4 label, so that's why I added the canvas since scrollbars can't be attached to labels or labelframes. Not sure if that's the right thing to do though. Commented Oct 7, 2011 at 8:54

3 Answers 3

20

To answer your specific question of how to stop a frame (or any container widget) from resizing to fit its contents, you call either pack_propagate(False) or grid_propagate(False) depending on which geometry manager you are using. If you've tried that and it wasn't working, you did it wrong. Since you didn't post that code we can't diagnose what went wrong.

When you call pack_propagate(False) you have to make sure that widget has an appropriate size. Labels and buttons will have a default size to fit their text, but a frame will have a default size of 1x1, making the contents nearly invisible. If using this on a frame, then, make sure to give it an explicit width and height.

Sign up to request clarification or add additional context in comments.

Comments

3

only Listbox, Text, Canvas, and Entry are scrollable by default; Canvas could work, but is a bit overkill IMO, so here's something that seems like what you want using Text

#!/usr/bin/python
from Tkinter import *
root = Tk()

descriptionFrame = Frame(root)

definitionFrame = LabelFrame(descriptionFrame, text="Definition")
definitionScroll = Scrollbar(definitionFrame)
definitionText = Text(definitionFrame, width=30, height=4, yscrollcommand=definitionScroll.set)
definitionScroll.config(command=definitionText.yview)

definitionText.delete("1.0", END)   # an example of how to delete all current text
definitionText.insert("1.0", "n/a") # an example of how to add new text to the text area

descriptionFrame.pack(fill=BOTH, expand=True)
definitionFrame.pack(fill=BOTH, expand=True)
definitionScroll.pack(side=RIGHT, fill=Y)
definitionText.pack(side=LEFT, fill=BOTH, expand=True)

root.mainloop()

Comments

1

What I did was set make my root un-resizable: root.resizable(False, False), then I defined width and height of the canvas: Canvas(root, height=500, width=1500) and finally placed my frame with a relative width and height of 1: frame.place(relheight=1, relwidth=1). Then I placed all my widgets with specific y/x values and pack(), but you could do the same process if you want everything sized to the canvas; I feel like this is a simpler method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.