Reputation: 1273
My understanding is that the in_
keyword argument to pack/grid should allow me to specify the managing widget. I want to pack arbitrary widgets inside a Frame subclass, so I passed the widgets and packed them during intialization, but the widgets didn't appear (although space in the window appears to have been allocated...). If I create the widget internally using master
which is root
, there is no issue and the widgets are displayed as expected.
The following working example and its output demonstrate the issue:
import tkinter as tk
from tkinter import ttk
class ItemContainerExternal(ttk.Frame):
def __init__(self, master, input_label, input_object):
ttk.Frame.__init__(self, master)
self.label = input_label
self.label.pack(side=tk.LEFT, padx=5, pady=3, fill=tk.X, in_=self)
self.input_object = input_object
self.input_object.pack(side=tk.LEFT, padx=5, pady=3, fill=tk.X, in_=self)
def get(self):
return variable.get()
class ItemContainerInternal(ttk.Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master)
ttk.Label(master, text='internal').pack(side=tk.LEFT, padx=5, pady=3, fill=tk.X, in_=self)
self.input_object = ttk.Entry(master)
self.input_object.pack(side=tk.LEFT, padx=5, pady=3, fill=tk.X, in_=self)
def get(self):
return variable.get()
if __name__ == '__main__':
root = tk.Tk()
inputobj = ttk.Entry(root)
inputlabel = ttk.Label(root, text='external')
ItemContainerExternal(root, inputlabel, inputobj).grid(row=0, column=0)
ItemContainerInternal(root).grid(row=1, column=0)
root.mainloop()
Upvotes: 0
Views: 300
Reputation: 5690
The order in which widgets get created matters. Newer widgets are "on top of" previous widgets.
Call .lower()
on the Frame after you create it, assuming it's created after all the widgets that you will pack into it. If not, you'll need to either call .lower()
again on the Frame after creating a new widget to go inside it, or you'll have to raise the new widget via .lift()
as per Bryan's answer.
Upvotes: 1
Reputation: 386240
The problem is that you're creating the entry and label before you're creating the frame, so they have a lower stacking order. That means the frame will be on top of the entry and label and thus, obscuring them from view.
A simple fix is to call lift()
on the entry and label:
class ItemContainerExternal(tk.Frame):
def __init__(self, master, input_label, input_object):
...
self.input_object.lift()
self.label.lift()
Upvotes: 2