I'd like to position one of my python tkinter Frames (ButtonWindow
) within my other Frame (MainWindow
), so that when I run the app the widgets in ButtonWindow
are present in MainWindow
along with the MainWindow
widget.
In the code below the Buttons from ButtonWindow
are present along with the MainWindow
Label, but the ButtonWindow
Label is missing.
I looked at the answers in Frame inside another frame In python Tkinter and tried to set the background to purple to understand where the borders of ButtonWindow
actually are, but I can't see any purple?
Thanks for any help!
import tkinter as tk
class ButtonWindow(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.bd = 5
self.bg = "purple"
self.label = tk.Label(text="Button window", font=12)
for i in range(3):
self.button = ttk.Button(text="button", command= lambda: button_fun())
self.button.pack(side = tk.LEFT)
def button_fun(self):
pass
class MainWindow(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.label = tk.Label(text="Main Window", font=12)
self.label.pack(pady=10,padx=10)
self.button_window = ButtonWindow()
self.button_window.pack()
app = MainWindow()
app.mainloop()
CodePudding user response:
If I understood correctly what you want is create a Main Frame with another frame inside it which include 3 buttons.
In this case, I changed a little bit your code to do that. One of the changes was replace the tk.Label
for the tk.LabelFrame
(This corrects the Label that was missing in the ButtonWindow
as you stated).
The second change that I suggest is to pass the MainFrame
to the ButtonWindow
as a parent frame. To do this I created the myCoreFrame
inside the MainWindow
class. Also, for all widgets I've set a parent frame.
import tkinter as tk
class ButtonWindow():
def __init__(self, Frame, *args, **kwargs):
self.label = tk.LabelFrame(Frame, text="Button window", font=12, bg = "purple")
self.label.pack()
for i in range(3):
self.button = tk.Button(self.label, text="button", command= lambda: button_fun())
self.button.pack(side = tk.LEFT)
def button_fun(self):
pass
class MainWindow():
def __init__(self, window, *args, **kwargs):
myCoreFrame = tk.Frame(window)
myCoreFrame.pack()
self.label = tk.LabelFrame(myCoreFrame, text="Main Window", font=12, bg = "red")
self.label.pack(pady=10,padx=10)
self.button_window = ButtonWindow(self.label)
root = tk.Tk()
app = MainWindow(root)
root.mainloop()
CodePudding user response:
The problem is that you aren't putting the labels and buttons inside frames. You need to explicitly set the frame as the parent of the button and label. If you don't, the widgets become children of the root window.
class ButtonWindow(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.label = tk.Label(self, text="Button window", font=12)
# ^^^^^^
for i in range(3):
self.button = ttk.Button(self, text="button", command= lambda: button_fun())
# ^^^^^^
...
class MainWindow(tk.Frame):
def __init__(self, *args, **kwargs):
...
self.label = tk.Label(self, text="Main Window", font=12)
# ^^^^^
self.label.pack(pady=10,padx=10)
self.button_window = ButtonWindow(self)
# ^^^^
...
CodePudding user response:
It is better to specify the parent of widgets when creating them, otherwise they will be children of root window.
Also you have never called any layout function on the "Button window" label so it is not visible.
self.bd = 5
and self.bg = "purple"
will not change the border width and the background color. Use self.config(bd=5, bg="purple")
instead.
import tkinter as tk
from tkinter import ttk
class ButtonWindow(tk.Frame):
def __init__(self, master=None, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.config(bd=5, bg="purple") # replace self.bd = 5 and self.bg = "purple"
self.label = tk.Label(self, text="Button window", font=12, fg='white', bg='purple') # specify parent
self.label.pack() # pack the label, otherwise it is not visible
for i in range(3):
self.button = ttk.Button(self, text="button", command=self.button_fun) # specify parent
self.button.pack(side=tk.LEFT)
def button_fun(self):
pass
class MainWindow(tk.Frame):
def __init__(self, master=None, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.label = tk.Label(self, text="Main Window", font=12) # specify parent
self.label.pack(pady=10, padx=10)
self.button_window = ButtonWindow(self) # specify parent
self.button_window.pack()
root = tk.Tk() # create root window explicitly
MainWindow(root).pack()
root.mainloop()
Also I have changed command=lambda: button_fun()
to command=self.button_fun
. The former one will raise exception when any of the buttons is clicked.