{"id":5910,"date":"2020-05-26T09:58:54","date_gmt":"2020-05-26T09:58:54","guid":{"rendered":"https:\/\/www.askpython.com\/?p=5910"},"modified":"2020-05-26T09:58:56","modified_gmt":"2020-05-26T09:58:56","slug":"tkinter-treeview-widget","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python-modules\/tkinter\/tkinter-treeview-widget","title":{"rendered":"Tkinter TreeView Widget"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hello again! As a part of our <a href=\"https:\/\/www.askpython.com\/python-modules\/tkinter\" class=\"rank-math-link\">Tkinter tutorial series<\/a>, today&#8217;s post will cover the TreeView widget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The TreeView widget is very useful if you want to display a hierarchy of items, with all attributes listed side by side.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if you want to construct an application which looks like the Windows File Explorer, we can do this using Tkinter&#8217;s TreeView widget.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"514\" src=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/windows_file_explorer-1-1024x514.png\" alt=\"Windows File Explorer 1\" class=\"wp-image-5913\" srcset=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/windows_file_explorer-1-1024x514.png 1024w, https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/windows_file_explorer-1-300x151.png 300w, https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/windows_file_explorer-1-768x386.png 768w, https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/windows_file_explorer-1.png 1069w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Windows File Explorer 1<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">So, what TreeView allows us to do is to build a tree-like structure and insert items accordingly, along with their attributes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can dynamically add or remove nodes from your Tree when you want to, so this is very useful for a lot of your GUI applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can construct the Tree according to our preference.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to replicate the file explorer, you&#8217;d create a TreeView of files with their attributes, and add nested files and folders as the children of the parent folders!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While we won&#8217;t be doing this exercise, I&#8217;d suggest you try this out on your own, so that you can get a good understand of how <code>TreeView<\/code> works.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s now look at how we can construct a TreeView widget, and perform operations on it &#8211; like insertion and deletion.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Construct a TreeView Widget<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The TreeView widget belongs to the <code>tkinter.ttk<\/code> module, so we must import this.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport tkinter.tk as ttk\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, we can refer to the widget as <code>ttk.TreeView()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To create a new TreeView widget, the syntax is simple.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ntree = ttk.Treeview(master, columns)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here, <code>tree<\/code> corresponds to the root node of the newly formed tree. Here, <code>master <\/code>refers to the main Tkinter application master node.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>columns<\/code> is a tuple, which refers to the names of the columns.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, we can construct a TreeView widget like this, having the columns &#8220;Name&#8221; and &#8220;ID&#8221;:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ntree = ttk.Treeview(master, columns=(&quot;Name&quot;, &quot;ID&quot;))\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This tree will be constructed using <code>master<\/code> as the base widget. Typically, you would want it to be the main master object of your application:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nmaster = tk.Tk()\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, while we have a TreeView widget, it makes no sense to display it since it is empty.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s first insert some objects, so that we can view the TreeView in our actual applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keep in mind that the rows of a TreeView node consists only of strings, like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&quot;Label&quot; , &quot;Hello&quot;, &quot;Second Col&quot;, &quot;Third Col&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s insert some nodes to our newly constructed TreeView.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Insert to a TreeView<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The insert syntax is very simple. We take the TreeView object, and insert some <code>values<\/code>, labelled using a <code>text<\/code>. We can also specify a unique ID for the node, using the <code>iid<\/code> parameter.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ntree.insert(parent, index, iid, text, values)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here, we insert the node to <code>parent<\/code>. If you want the <code>parent<\/code> widget as the master (root) node, we can set this to the empty string (&#8221;). Otherwise, we must mention the <code>iid<\/code> of an existing parent node.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The child number of this node is referenced using <code>index<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if you want to insert at the first child, you specify <code>index=0<\/code>. If you want to insert at the end, you can mention the special value <code>'end'<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ntree.insert(parent=&#039;&#039;, index=&#039;end&#039;, iid=0, text=&quot;Label&quot;, values=(&quot;Hello&quot;, &quot;Second Col&quot;, &quot;Third Col&quot;))\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The above is an example of inserting to the end of a root node, with the values as the below row:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n&quot;Label&quot; , &quot;Hello&quot;, &quot;Second Col&quot;, &quot;Third Col&quot;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Unfortunately, there isn&#8217;t an easy way to construct a TreeView, since you need other widgets to visualize the output properly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Please ensure that you have gone through our tutorial sections on the <a href=\"https:\/\/www.askpython.com\/python-modules\/tkinter\/tkinter-buttons\" class=\"rank-math-link\">Tkinter Button<\/a>, <a href=\"https:\/\/www.askpython.com\/python-modules\/tkinter\/python-tkinter-grid-example\" class=\"rank-math-link\">Grid Manager<\/a>, and <a href=\"https:\/\/www.askpython.com\/python-modules\/tkinter\/tkinter-entry-widget\" class=\"rank-math-link\">Tkinter Entry<\/a> widgets before proceeding further.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ll provide a sample application to visualize the output, using these widgets:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport tkinter as tk\nimport tkinter.ttk as ttk\n\nclass Application(tk.Frame):\n    def __init__(self, root):\n        self.root = root\n        self.initialize_user_interface()\n\n    def initialize_user_interface(self):\n        # Configure the root object for the Application\n        self.root.title(&quot;Application&quot;)\n        self.root.grid_rowconfigure(0, weight=1)\n        self.root.grid_columnconfigure(0, weight=1)\n        self.root.config(background=&quot;green&quot;)\n\n        # Define the different GUI widgets\n        self.name_label = tk.Label(self.root, text=&quot;Name:&quot;)\n        self.name_entry = tk.Entry(self.root)\n        self.name_label.grid(row=0, column=0, sticky=tk.W)\n        self.name_entry.grid(row=0, column=1)\n\n        self.idnumber_label = tk.Label(self.root, text=&quot;ID&quot;)\n        self.idnumber_entry = tk.Entry(self.root)\n        self.idnumber_label.grid(row=1, column=0, sticky=tk.W)\n        self.idnumber_entry.grid(row=1, column=1)\n\n        self.submit_button = tk.Button(self.root, text=&quot;Insert&quot;, command=self.insert_data)\n        self.submit_button.grid(row=2, column=1, sticky=tk.W)\n\n        self.exit_button = tk.Button(self.root, text=&quot;Exit&quot;, command=self.root.quit)\n        self.exit_button.grid(row=0, column=3)\n\n        # Set the treeview\n        self.tree = ttk.Treeview(self.root, columns=(&#039;Name&#039;, &#039;ID&#039;))\n\n        # Set the heading (Attribute Names)\n        self.tree.heading(&#039;#0&#039;, text=&#039;Item&#039;)\n        self.tree.heading(&#039;#1&#039;, text=&#039;Name&#039;)\n        self.tree.heading(&#039;#2&#039;, text=&#039;ID&#039;)\n\n        # Specify attributes of the columns (We want to stretch it!)\n        self.tree.column(&#039;#0&#039;, stretch=tk.YES)\n        self.tree.column(&#039;#1&#039;, stretch=tk.YES)\n        self.tree.column(&#039;#2&#039;, stretch=tk.YES)\n\n        self.tree.grid(row=4, columnspan=4, sticky=&#039;nsew&#039;)\n        self.treeview = self.tree\n\n        self.id = 0\n        self.iid = 0\n\n    def insert_data(self):\n        self.treeview.insert(&#039;&#039;, &#039;end&#039;, iid=self.iid, text=&quot;Item_&quot; + str(self.id),\n                             values=(&quot;Name: &quot; + self.name_entry.get(),\n                                     self.idnumber_entry.get()))\n        self.iid = self.iid + 1\n        self.id = self.id + 1\n\napp = Application(tk.Tk())\napp.root.mainloop()\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here, I have created some labels and entries for the input. I&#8217;ve also created a TreeView, which comprises of two parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The TreeView Headings (To display the column names)<\/li><li>The TreeView Columns and the <code>insert_data()<\/code> method<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever we press the &#8220;Insert&#8221; button, the <code>insert_data()<\/code> method will be called on our TreeView widget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, enough of talking. Let&#8217;s now test our program for insertion!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1770\" height=\"690\" src=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/treeview-example-1.gif\" alt=\"Treeview Example 1\" class=\"wp-image-5955\"\/><figcaption>Treeview Example<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Okay, that seems to work quite well! Let&#8217;s now add a Delete button so that we can delete a selected row.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Deleting a row from the TreeView<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There exists a <code>TreeView.delete()<\/code> method that we can take advantage of. This will delete the corresponding node (row, in our case) from our TreeView widget.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ntree.delete(iid)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This simply takes the <code>iid<\/code> Identification Number of the node, and deletes it from the TreeView!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll wrap this up on a method called <code>delete_data()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, the big question is how we can get the id number of our row, from the TreeView widget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Well, this depends on <em>how<\/em> you&#8217;re going to be performing the deletion operation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll delete a row whenever we select that row using the mouse. After the row gets highlighted, we can press the delete button, and this will remove it from the <code>TreeView<\/code> widget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do this, we will use the <code>TreeView.focus()<\/code> method, to get the <code>iid<\/code> of the row (as a string). We can use this to delete that row directly!<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n    def delete_data(self):\n        row_id = int(self.tree.focus())\n        self.treeview.delete(row_id)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s add a delete button and use this method as a callback function!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After adding it, the application will look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport tkinter as tk\nimport tkinter.ttk as ttk\n\nclass Application(tk.Frame):\n    def __init__(self, root):\n        self.root = root\n        self.initialize_user_interface()\n\n    def initialize_user_interface(self):\n        # Configure the root object for the Application\n        self.root.title(&quot;Application&quot;)\n        self.root.grid_rowconfigure(0, weight=1)\n        self.root.grid_columnconfigure(0, weight=1)\n        self.root.config(background=&quot;green&quot;)\n\n        # Define the different GUI widgets\n        self.name_label = tk.Label(self.root, text=&quot;Name:&quot;)\n        self.name_entry = tk.Entry(self.root)\n        self.name_label.grid(row=0, column=0, sticky=tk.W)\n        self.name_entry.grid(row=0, column=1)\n\n        self.idnumber_label = tk.Label(self.root, text=&quot;ID:&quot;)\n        self.idnumber_entry = tk.Entry(self.root)\n        self.idnumber_label.grid(row=1, column=0, sticky=tk.W)\n        self.idnumber_entry.grid(row=1, column=1)\n\n        self.submit_button = tk.Button(self.root, text=&quot;Insert&quot;, command=self.insert_data)\n        self.submit_button.grid(row=2, column=1, sticky=tk.W)\n\n        self.delete_button = tk.Button(self.root, text=&quot;Delete&quot;, command=self.delete_data)\n        self.delete_button.grid(row=100, column=100)\n\n        self.exit_button = tk.Button(self.root, text=&quot;Exit&quot;, command=self.root.quit)\n        self.exit_button.grid(row=0, column=3)\n\n        # Set the treeview\n        self.tree = ttk.Treeview(self.root, columns=(&#039;Name&#039;, &#039;ID&#039;))\n\n        # Set the heading (Attribute Names)\n        self.tree.heading(&#039;#0&#039;, text=&#039;Item&#039;)\n        self.tree.heading(&#039;#1&#039;, text=&#039;Name&#039;)\n        self.tree.heading(&#039;#2&#039;, text=&#039;ID&#039;)\n\n        # Specify attributes of the columns (We want to stretch it!)\n        self.tree.column(&#039;#0&#039;, stretch=tk.YES)\n        self.tree.column(&#039;#1&#039;, stretch=tk.YES)\n        self.tree.column(&#039;#2&#039;, stretch=tk.YES)\n\n        self.tree.grid(row=4, columnspan=4, sticky=&#039;nsew&#039;)\n        self.treeview = self.tree\n\n        self.id = 0\n        self.iid = 0\n\n    def insert_data(self):\n        self.treeview.insert(&#039;&#039;, &#039;end&#039;, iid=self.iid, text=&quot;Item_&quot; + str(self.id),\n                             values=(&quot;Name: &quot; + self.name_entry.get(),\n                                     self.idnumber_entry.get()))\n        self.iid = self.iid + 1\n        self.id = self.id + 1\n\n    def delete_data(self):\n        row_id = int(self.tree.focus())\n        self.treeview.delete(row_id)\n\napp = Application(tk.Tk())\napp.root.mainloop()\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Output<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1300\" height=\"712\" src=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2020\/05\/treeview-delete.gif\" alt=\"Treeview Delete\" class=\"wp-image-5958\"\/><figcaption>Treeview Delete<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we have the basic structure of the TreeView completed, and also implemented bare-bones insertion and deletion operations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;d suggest you to add more functionality to this application by dealing with other operations, such as updating some rows. You may also notice that the item numbers are not ordered properly after deletion.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a simple template function for <code>update()<\/code> that you can use as a reference:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef update(self):\n    for idx, node in enumerate(self.treeview.get_children()):\n        self.tree.item(node, text=&quot;Updated_Item_&quot; + str(idx))\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This updates all the rows of your <code>TreeView<\/code> and changes your <code>text<\/code> label. You can modify other attributes similarly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These are among the various improvements that you could make to your application.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hopefully, you&#8217;ve got this simple application working using <code>TreeView<\/code>. We briefly looked at how we could use this widget to display rows and columns of our application, structured as a Tree.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-background has-vivid-green-cyan-background-color has-vivid-green-cyan-color\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Hello again! As a part of our Tkinter tutorial series, today&#8217;s post will cover the TreeView widget. The TreeView widget is very useful if you want to display a hierarchy of items, with all attributes listed side by side. For example, if you want to construct an application which looks like the Windows File Explorer, [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":6051,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[92],"tags":[],"class_list":["post-5910","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tkinter"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/5910","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=5910"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/5910\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/6051"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=5910"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=5910"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=5910"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}