Python Tkinter - Scrollable canvas containing expandable widgets - python

I'm using Python Tkinter and I want to place a variable number of text box widgets in a frame or canvas. The text boxes are packed vertically down the frame, so the first one is on top, the second one is found below, etc.. I can have all the button, listbox, etc widgets in a "left section" of the GUI, while a "right section" will only contain the text box widgets. I want the text box widgets to horizontally expand when the master window is maximized, but because there's a variable number of these widgets, the "right section" containing the text boxes also needs to be able to vertically scroll to view them all.
Currently, I'm using Canvas.create_window to add my variable number of text boxes to the canvas, and while I can scroll the canvas to view all the text boxes, they do not horizontally expand when I resize the window. I have an alternate GUI that uses a frame for the "right section", which allows the widgets to horizontally expand, but if too many are packed, I cannot scroll the frame to see the additional text boxes because I can't have a scroll bar tied to a frame.
Is there any way around this trade-off?

The solution is pretty simple: bind to the <Configure> event of the canvas -- this will cause your callback to be called whenever the canvas widget is resized. You then simply need to get the width of the canvas and use that to iteratively resize all the embedded windows.

Related

Draw line on text widget in Tkinter [duplicate]

I was wondering whether it is possible to use some of the tkinter canvas drawing methods on a text widget. Ideally I would have the text widget placed onto the canvas so that I can draw onto the canvas and make it look like it shows up on the text widget.
No, it is not possible to draw over or into a tkinter Text widget. You can, however, add text to a canvas with the create_text method and draw over that.

Tkinter title with line around area

So in tkinter I'm making a program, I want to know can you make a title box thing like the one in this image with the title "Booking Details"?
Sounds like you want a Label Frame.
The LabelFrame widget is a variant of the Tkinter Frame widget. By default, it draws a border around its child widgets, and it can also display a title.

Python Tkinter - How to move a textbox by pixels

What the title says.
I'm having a problem moving the textbox from a side to side.
The code's long and it's about 200+ lines so I wont post it here.
Anybody has an idea?
You have various options for this, depending on what you mean by "text box," and whether you want to move it "by pixels" or "from a side to [another] side."
If you just want to display text, you can use a Label widget. If you want a text box where the user can enter text, try an Entry widget. If you want to move your widget from one area of the screen to another, you can use the grid geometry manager and simply use grid_forget to "unplace" your widget then grid (with different options than you originally used, of course) to put it somewhere else.
If you just have text and you'd like to move it pixel by pixel, you could create a Canvas and then use that widget's create_text method to create some text in a specific place on the Canvas. You can the use the Canvas widget's itemconfig method to move the text to a new location.
If you need something more complex than text, like an Entry widget, and you want to move it pixel by pixel, do the same as above but use the create_window method instead.
See Canvas, grid, Label, Entry, and these SO questions about create_window.

PyGTK/Glade keep button size standard

I have a simple pygtk/glade window with a menu and a 3x3 grid. Each row of the grid consists on: two labels and a button.
When the Window is resized, the labels holds the same font size, but the buttons get resized, and they could become HUGE if the windows gets very big.
How could I manage to keep my buttons with the same size always (the "standar" size of a button, just like they are when the interface is just opened) no matter if the Window is resized?
You just have to set the fill and expand parameters of the Buttons to False (uncheck them in the Glade interface).
You would also want to put each button at the center of a 3x3 GtkTable, so it will appear centered and not aligned at the top of the cell

Resizing a Scrolled Tkinter Text Box

I'd like a to make a scrolled Tkinter textbox that fills the maximum alloted space. I have it working kind of...
For some reason when I stretch the window the text widget is fine; However, the scroll bar gets a ton of padding on the x axis.
The second problem is when I shrink the window the scrollbar goes of the screen.
Anyone know the solutions to these two programs?
snippet:
self.Fr = Tkinter.Frame(self, width=self.Wi, height=self.He)
self.Fr.pack(side='right', fill='both', expand='yes')
self.Te = Tkinter.Text(self.Fr, font=self.Fo, fg=self.FG, bg=self.BG,
selectforeground=self.SFG,
selectbackground=self.SBG,
insertbackground=self.IBG, wrap='word',
undo=True, maxundo=100)
#self.Te.grid(column=0, row=0, sticky='NSEW')
self.Te.pack(side='left', fill='both', expand='yes')
self.Sc = Tkinter.Scrollbar(self.Fr, elementborderwidth=1)
#self.Sc.grid(column=1, row=0, sticky='NSEW')
self.Sc.pack(side='right', fill='both', expand='yes')
self.Te.configure(yscrollcommand=self.Sc.set)
self.Sc.configure(command=self.Te.yview)
Your scrollbar gets all the padding because you use fill='both'. Even though it's a vertical scrollbar you asked it to take up extra space along the x axis, which results in the padding since the scrollbar itself won't stretch to make a wide scrollbar. You want vertical scrollbars to only fill in the Y direction and horizontal ones to fill in the X direction.
As to the scrollbar going off screen, that's a little complex to explain but it has a simple solution.
The problem is this: if you shrink a window managed by pack to a point where it's smaller than that required by the widgets inside, it starts clipping widgets. The way this works is it processes the widgets in order, laying out the window and then allocating any left-over space for any remaining widgets. This means that if a widget early in the order takes up all the remaining visual space, any later widgets will not appear.
The "order" mentioned above is the order of the packing list. Specifically, the order in which items were packed. So, if you pack the text widget and then the scrollbar Tk will first lay out the text widget, and any remaining space will be allocated to the scrollbar. IF you had packed the scrollbar first, it would get laid out and any remaining space would be given to the text widget.
It all sounds very complex, but the cool thing is that if you pack things in the proper order it all just works.
The general rule of thumb, then, is to make sure the last widget you pack is the one with expand set to true. This is your "elastic" widget. That way all the fixed-size widgets will take up whatever space they need first, and your "elastic" widget will take up all that is left.
There is another solution which is to give your text widget a requested width and height of one. With that, when the packer initially allocates space it will allocate only a small amount of space. Thus, when the window shrinks the text widget will shrink until it gets down to that tiny size. This isn't very practical though, since one of the great features of pack is that you can give all widgets their natural size (or they assume their natural size based on their content in the case of buttons and labels) and the packer does all the work. If you set the width and height to one, your initial window (unless explicitly set to a larger size) will be rather small.
This behavior is all documented in the man page for pack, though you have to read it really closely to fully grasp this behavior.

Categories