How to get an all sticky grid of Treeview and Scrollbar in Python Tkinter?
<p>What I want in Tkinter in Python 2.7 is the following grid layout:</p>

<p><a href="http://i.stack.imgur.com/O1jHM.png" rel="nofollow"><img src="http://i.stack.imgur.com/O1jHM.png" alt="Grid Layout"></a></p>

<p>However once, I start using the <code>grid()</code> functions instead of <code>pack()</code> functions, nothing is showing on running the script. The following is what I am stuck with:</p>

<pre><code>import Tkinter, ttk

class App(Tkinter.Frame):
    def __init__(self,parent):
        Tkinter.Frame.__init__(self, parent, relief=Tkinter.SUNKEN, bd=2)
        self.parent = parent        
        self.grid(row=0, column=0, sticky="nsew")
        self.menubar = Tkinter.Menu(self)
        try:
            self.parent.config(menu=self.menubar)
        except AttributeError:
            self.tk.call(self.parent, "config", "-menu", self.menubar)    

        self.tree = ttk.Treeview(self.parent)
        self.tree.grid(row=0, column=0, sticky="nsew")

        self.yscrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
        self.yscrollbar.grid(row=0, column=1, sticky='nse')
        self.tree.configure(yscrollcommand=self.yscrollbar.set)
        self.yscrollbar.configure(command=self.tree.yview)

if __name__ == "__main__":
    root = Tkinter.Tk()
    root.title("MyApp")
    app = App(root)
    app.pack()
    app.mainloop()
</code></pre>

<p>Any help will be highly appreciated.</p>

<p>You have several problems that are affecting your layout. </p>

<p>First, some of the widgets inside <code>App</code> use <code>self</code> as the parent, some use <code>self.parent</code>. They should all use <code>self</code> in this particular case. So, the first thing to do is change the parent option of the <code>Treeview</code> to <code>self</code>.</p>

<pre><code>self.tree = ttk.Treeview(self)
</code></pre>

<p>Second, since your main code is calling <code>app.pack()</code>, you shouldn't be calling <code>self.grid</code>. Remove the line `self.grid(row=0, column=0, sticky="nsew"). It's redundant.</p>

<p>Third, you are using very unusual code to add the menubar. You need to configure the menu of the root window. There's no need to put this in a <code>try/except</code> block, and there's no reason to use <code>self.tk.call</code>. Simply do this:</p>

<pre><code>self.parent.configure(menu=self.menubar)
</code></pre>

<p>This assumes that <code>self.parent</code> is indeed the root window. If you don't want to force that assumption you can use <code>winfo_toplevel()</code> which will always return the top-most window:</p>

<pre><code>self.parent.winfo_toplevel().configure(menu=self.menubar)
</code></pre>

<p>Finally, since you are using <code>grid</code>, you need to give at least one row and one column a "weight" so tkinter knows how to allocate extra space (such as when the user resizes a window).</p>

<p>In your case you want to give all of the weight to row and column 0 (zero), since that's where you've placed the widget which needs the most space:</p>

<pre><code>def __init__(self, parent):
    ...
    self.grid_rowconfigure(0, weight=1)
    self.grid_columnconfigure(0, weight=1)
</code></pre>

<p>Note: you'll also want to make sure when you call <code>app.pack()</code> that you give it parameters that makes it fill any extra space, too. Otherwise the tree will fill "app", but "app" would not fill the window.</p>

<pre><code>app.pack(fill="both", expand=True)
</code></pre>

<p>Here is a fully working example with all of those changes. I grouped the main layout code together since that makes the code easier to visualize and easier to maintain:</p>

<pre><code>import Tkinter, ttk

class App(Tkinter.Frame):
    def __init__(self,parent):
        Tkinter.Frame.__init__(self, parent, relief=Tkinter.SUNKEN, bd=2)
        self.parent = parent        

        self.menubar = Tkinter.Menu(self)
        self.parent.winfo_toplevel().configure(menu=self.menubar)

        self.tree = ttk.Treeview(self)

        self.yscrollbar = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
        self.tree.configure(yscrollcommand=self.yscrollbar.set)

        self.tree.grid(row=0, column=0, sticky="nsew")
        self.yscrollbar.grid(row=0, column=1, sticky='nse')
        self.yscrollbar.configure(command=self.tree.yview)

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

if __name__ == "__main__":
    root = Tkinter.Tk()
    root.title("MyApp")
    app = App(root)
    app.pack(fill="both", expand=True)
    app.mainloop()
</code></pre>

<hr>

<p>Your question mentioned grid, but in this case you could save a few lines of code by using <code>pack</code>. <code>pack</code> excels in layouts like this, where your gui is aligned top-to-bottom and/or left-to-right. All you need to do is replace the last five lines (the calls to <code>grid</code>, grid_rowconfigure<code>and</code>grid_columnconfigure`) with these two lines:</p>

<pre><code>self.yscrollbar.pack(side="right", fill="y")
self.tree.pack(side="left", fill="both", expand=True)
</code></pre>

python python-2.7 tkinter treeview