I just started to learn python and tried to setup a simple GUI with Tkinter.
I am having problems understanding the grid feature of Tkinter.
I want to create a GUI, where I can dynamically add new frames with a fixed setup. For simplicity, I just used labels in this example.
This is my code:
from tkinter import *
def newLabelWithContent(root, name):
frame = Frame(root)
frame.grid_columnconfigure(tuple(range(18)), weight=1)
frame.grid_rowconfigure(0, weight=1)
frame.pack(fill="both", side = TOP)
Label(frame, text=name, borderwidth=2, relief="groove").grid(column=0, row=0, sticky="news", columnspan=6)
Label(frame, text="Actual", borderwidth=2, relief="groove").grid(column=6, row=0, sticky="news", columnspan=4)
Label(frame, text="Unit", borderwidth=2, relief="groove").grid(column=10, row=0, sticky="news", columnspan=1)
Label(frame, text="Type", borderwidth=2, relief="groove").grid(column=11, row=0, sticky="news", columnspan=1)
Label(frame, text="Set Value", borderwidth=2, relief="groove").grid(column=12, row=0, sticky="news", columnspan=4)
Label(frame, text="Set-/Action-Button", borderwidth=2, relief="groove").grid(column=16, row=0, sticky="news", columnspan=2)
for widget in frame.winfo_children():
widget.grid(padx=0, pady=2)
root = Tk()
root.title("BaseTopic")
root.geometry("500x200")
newLabelWithContent(root, "First Element")
newLabelWithContent(root, "Second Elemnt")
newLabelWithContent(root, "Short")
newLabelWithContent(root, "Looooooooooooooooooooong")
root.mainloop()
But I want that all columns have the same size, no matter which text is displayed on the labels. So it looks more like a table. When the window is resized the labels should resize too.
CodePudding user response:
It is hard to align those labels if they are in different frames. Put all of them inside same frame instead.
from tkinter import *
def newLabelWithContent(frame, name):
cols, rows = frame.grid_size()
Label(frame, text=name, borderwidth=2, relief="groove").grid(column=0, row=rows, sticky="news", columnspan=6)
Label(frame, text="Actual", borderwidth=2, relief="groove").grid(column=6, row=rows, sticky="news", columnspan=4)
Label(frame, text="Unit", borderwidth=2, relief="groove").grid(column=10, row=rows, sticky="news", columnspan=1)
Label(frame, text="Type", borderwidth=2, relief="groove").grid(column=11, row=rows, sticky="news", columnspan=1)
Label(frame, text="Set Value", borderwidth=2, relief="groove").grid(column=12, row=rows, sticky="news", columnspan=4)
Label(frame, text="Set-/Action-Button", borderwidth=2, relief="groove").grid(column=16, row=rows, sticky="news", columnspan=2)
for widget in frame.winfo_children():
widget.grid(padx=0, pady=2)
root = Tk()
root.title("BaseTopic")
root.geometry("800x200")
frame = Frame(root)
frame.pack(fill='both', expand=1)
frame.grid_columnconfigure(tuple(range(18)), weight=1)
newLabelWithContent(frame, "First Element")
newLabelWithContent(frame, "Second Elemnt")
newLabelWithContent(frame, "Short")
newLabelWithContent(frame, "Looooooooooooooooooooong")
root.mainloop()
CodePudding user response:
Use width
argument of Label
.
Change:
Label(frame, text=name, borderwidth=2, relief="groove").grid(column=0, row=0, sticky="news", columnspan=6)
To:
Label(frame, text=name, borderwidth=2, relief="groove", width=10).grid(column=0, row=0, sticky="news", columnspan=6)
Note that if you want all the text to show up you will want to either calculate what is the maximum width you will enter before you enter any, or you will need to iterate all the Label
s and change their width if the maximum width changed or as said in comments put them all in one frame.