Multiple frames in a single tab ttk.Notebook - python

I have the following sections of code (not complete) where I would like to contain several frames into a single tab in the ttk 'Notebook' .
win1 = Tk()
n = ttk.Notebook(win1)
choice_frame = ttk.Frame(n, style="Black.TLabel")
choice_frame.grid(row=2, column=1, sticky="N,S,E,W", padx=1, pady=1)
choice_frame.grid_columnconfigure(0, weight=3)
choice_frame.grid_rowconfigure(0, weight=1)
frame_text = ttk.Frame(n, style="Black.TLabel")
frame_text.grid(row=0, column=0, sticky = "N")
frame_text.grid_columnconfigure(0, weight=3)
frame_text.grid_rowconfigure(0, weight=1)
frame_table = ttk.Frame(n, style="Black.TLabel")
frame_table.grid(row=2, column=0, padx=1, pady=1, sticky= " N, S, E, W ")
frame_table.grid_columnconfigure(0, weight=3)
frame_table.grid_rowconfigure(0, weight=1)
n.add(frame_table, text="One") # Would like same tab not two separate ones
n.add(choice_frame, text="One")
n.grid(sticky="N")
I would also like to know if there's a way of allowing every dimension to adjust automatically when the window is dragged out and maximised. I have previously tried:
frame_table.grid_propagate(0)
But this doesn't seem to allow the height as well as width dimension to stick. I would like my 'table' to be in the center of the window but adjust with the window size.
Thank you for your help!

grid_propagate isn't a solution to any of your problems.
Each tab can contain only a single frame, but that single frame can contain whatever you want. So, create one container frame for the tab and then put all your other frames in the container frame. This is one of the main reasons the Frame class exists -- to build widget containers that facilitate layout.
As for the resizing, the problem is probably that you're not adding a weight to the rows and columns of the main window. Though it could also be related to the fact you are using grid to place the frames in the notebook; you can't use grid to place items in a notebook.

Related

Write Multiple Lines in Tkinter Entry

I'm trying to make a Tkinter entry of a big size (I want to write multiple paragraphs inside it). I tried to achieve that by increasing ipady and ipadx (entry.grid(row =0, column = 0, ipadx = 50, ipady = 50))and it resulted in a bigger entry, but the text still gets written in only one line and doesn't fill the whole entry. What do you suggest doing?
Here's a screenshot of the entry.
You can use the Text widget
import tkinter as tk
window = tk.Tk()
window.geometry('400x200')
t = tk.Text(window, width=100, height=100)
t.grid(column=1, row=15)
window.mainloop()

Python: Using .grid() to fill the whole frame width with 5 columns [duplicate]

I was wondering if any of you Tkinter experts out there could help me with a question, do any of you know if there is a alternative to packs fill=X or fill=Y commands for grids? Or some code that would add in this function?
(I have searched around for a bit and couldn't find anything)
Use the sticky attribute to make objects fill the row and/or column that they are in.
Apply a weight to the rows and/or columns to get them to use any extra space in the container using grid_rowconfigure and grid_columnconfigure. The "weight" defines how grid will allocate any extra space once all the children are arranged. By default, rows and columns have zero weight, meaning they don't use any extra space.
For example:
frame = tk.Frame(...)
l1 = tk.Label(frame, ...)
l2 = tk.Label(frame, ...)
l1.grid(row=0, column=0, sticky="nsew")
l2.grid(row=1, column=1, stickky="nsew")
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)

Position the button in right place Tkinter

How can I position the two button close to eachother. I am getting the output as shown in the picture below.
_scrape_btn = ttk.Button(_mainframe, text='Scrape!', command=save)
_scrape_btn.grid(row=2, column=0)
_compress_btn = ttk.Button(_mainframe, text='Compress!', command=compress)
_compress_btn.grid(row=2, column=1)
Looking at your image, I can tell that your URL and Content LabelFrames have been put into row=0, column=0 and row=1, column=0 respectively. So you should now realise that the width of the first column is as large as the labelframe. Hence your 2nd button starts where the 1st column ends since it on the 2nd column.
What you can do is add columnspan=2 in both the labelFrames.
Now by default the buttons will be center aligned. To bring them close together, you need to add sticky='e' in the grid command of the 1st button (Scrape) and sticky='w' in the grid command of the 2nd button (Compress).

Mass creation of widgets

I'm using tkinter to create a calculator of sorts for one of my classes, and I've been making like 20 labels in a grid layout, using virtually the same line of code every time except the name and obviously the row number. I was just wondering if there was a standard way to quickly and effeciently make labels like this, or if someone has a quick way they use to break the tediousness?
For example, this is what my "code" basically looked like.
label0 = tk.Label(frame,
text="Label0")
label0.grid(row=0,
column=0,
sticky="E")
label1 = tk.Label(frame,
text="Label1")
label1.grid(row=1,
column=0,
sticky="E")
...
labeln = tk.Label(frame,
text="Labeln")
labeln.grid(row=n,
column=0,
sticky="E")
I tried creating a list or library of all the label names, then saying something like
labelnames = ["label0",
"labebl1",
...,
"labeln"]
for i in len(labelnames):
labelx = tk.Label(frame,
text=labelnames[i])
labelx.grid(row=i,
column=0,
sticky="E")
This works, but the point of this was to learn and I would like to know if there is a standard or "correct" way to do this. I tend to stray away from using classes because I still don't understand them (ironic I know), but I would like to learn if this were a better use for them.
A problem with this method that arises for me is I have an entry box corresponding to each label created using a similar loop, and I'm not sure how to get the input from the entry this way.
You are doing it correctly. We could make it a little neater using enumerate:
labels = []
for i, label in enumerate(labelnames):
labelx = tk.Label(frame, text=label)
labelx.grid(row=i, column=0, sticky="E")
labels.append(labelx)
I also added the resulting widgets to a list. That way I can access them later.
labels[2].config(text='new text') # update the text on the 3rd Label

List of tkinter widget using a loop doesn't show up

Please allow me to explain the problem I am facing. I am a undergraduate student who started learning Python a couple of month ago. So, I am new and please bear with me if the experts found them rather naive.
The intention was very simple. I want to place 5 menu buttons in parallel (say in one row, well, this is not the pressing issue though) in a tkinter parent frame. What I did was to introduce 5 sub-frames and place the menu button on them one by one. The idea to use sub-frame was to make space for centering and better layout. Using the most straight-forward fashion, I did it one by one: Define a sub-frame and place a menu button. It all worked well.
Now I am trying to avoid the repeated codes and to lay out the menu buttons and sub-frames using for loops, since the sub-frames and buttons are technically identical except the gird locations and labels are different. I came up with the following code.
Python compiler didn't report any errors. But, only the last button ("Other") was displayed while other buttons are missing. I am having difficulty sorting out what exactly went wrong.
indBtnFrame = [tkinter.Frame(self.parent)] * 5
for i in range(len(indBtnFrame)):
column_index = (i+1)*2
indBtnFrame[i].grid(column=column_index,
row=0,
columnspan=2,
rowspan=1,
sticky="WENS")
for r in range(1): # 1 row in total.
indBtnFrame[i].rowconfigure(r, weight=1)
for c in range(1): # 1 column in total.
indBtnFrame[i].columnconfigure(c, weight=1)
# To fix the grid size.
indBtnFrame[i].grid_propagate(False)
indBtnLabel = ["Street",
"City",
"Postcode",
"Province",
"Other"]
indBtn = []
for i in range(len(indBtnLabel)):
button_label = tkinter.StringVar()
button_label.set(str(indBtnLabel[i]))
temp_widget = tkinter.Menubutton(indBtnFrame[i],
textvariable=button_label,
relief=tkinter.GROOVE)
indBtn.append(temp_widget)
for i in range(len(indBtn)):
indBtn[i].grid(column=0, row=0,
columnspan=1, rowspan=1,
sticky="WENS")
indBtn[i].menu = tkinter.Menu(indBtn[i], tearoff=0)
indBtn[i]["menu"] = indBtn[i].menu

Categories

Resources