Issue
I want to create a GUI, that has two labels at the bottom of the GUI for status (Status 0
and Status 1
) and the the upper part of the GUI, that has all the GUI stuff of the main application.
Basically the GUI layout should look like this:
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━┓
┃ @ ┃ hello world ┃ ╳ ┃
┣━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━┫
┃ ┃ <- Frame 0
┃ MAIN ┃ <- Frame 0
┃ ┃ <- Frame 0
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ OTHER ┃ <- Frame 1
┣━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┫ <- Frame 1
┃ Status 0 ┃ Status 1 ┃ <- Frame 1
┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
However, my code produces something like this
or even worse, on resize something like this
My question therefore is, how can I set the Status 0
and Status 1
widths independently to something like
Status 0
shall be 2/3 of the current window widthStatus 1
shall be 1/3 of the current window width
import tkinter as tk
class MyApp(tk.Tk):
def __init__(self):
super().__init__()
self.frame0 = tk.Frame(self, background="green")
self.title('hello world')
self.frame0.pack(fill=tk.X)
self.frame0_label0 = tk.Label(self.frame0, text='MAIN', border=10)
self.frame0_label0.grid(row=0, column=0)
self.frame1 = tk.Frame(self, background="blue")
self.frame1.pack(fill=tk.X)
self.frame1_label0 = tk.Label(self.frame1, text='OTHER', border=10)
self.frame1_label0.grid(row=0, column=0)
self.var0 = tk.StringVar()
self.var0.set("S0")
self.var1 = tk.StringVar()
self.var1.set("S1")
sbar0 = tk.Label(self.frame1, textvariable=self.var0, relief=tk.SUNKEN, anchor="w")
sbar1 = tk.Label(self.frame1, textvariable=self.var1, relief=tk.SUNKEN, anchor="w")
sbar0.grid(row=1, column=0)
sbar1.grid(row=1, column=1)
def main():
MyApp().mainloop()
if __name__ == "__main__":
main()
Solution
In my opinion, the simplest solution is to put the status labels in a separate frame using grid
. With that, you can control their layout more easily without affecting any other part of the UI.
So, start by adding the statusbar frame and make sure it is below the other frames.
self.sbar = tk.Frame(self)
self.sbar.pack(side="bottom", fill="x")
Next, place the labels in this frame and configure appropriately:
sbar0 = tk.Label(self.sbar, textvariable=self.var0, relief=tk.SUNKEN, anchor="w")
sbar1 = tk.Label(self.sbar, textvariable=self.var1, relief=tk.SUNKEN, anchor="w")
self.sbar.grid_columnconfigure(0, weight=2)
self.sbar.grid_columnconfigure(1, weight=1)
sbar0.grid(row=1, column=0, sticky="ew")
sbar1.grid(row=1, column=1, sticky="ew")
You'll also want to make sure that your "main" frame is properly packed to fill the majority of the window:
self.frame0.pack(fill=tk.BOTH, expand=True)
Personally I find layout problems much easier to solve when you group all of the layout code together for children of a widget, instead of interspersing it with the code that creates the widget.
For example, this makes the outermost layout much easier to visualize in the code.
self.frame0 = tk.Frame(self, background="green")
self.frame1 = tk.Frame(self, background="blue")
self.sbar = tk.Frame(self)
self.frame0.pack(side="top", fill="both", expand=True)
self.frame1.pack(side="top", fill="x")
self.sbar.pack(side="bottom", fill="x")
Answered By - Bryan Oakley
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.