{"id":3579,"date":"2019-09-14T07:44:06","date_gmt":"2019-09-14T05:44:06","guid":{"rendered":"https:\/\/pythonprogramming.altervista.org\/?p=3579"},"modified":"2019-09-14T07:44:06","modified_gmt":"2019-09-14T05:44:06","slug":"python-ebooks-maker-4-save-files","status":"publish","type":"post","link":"https:\/\/pythonprogramming.altervista.org\/python-ebooks-maker-4-save-files\/","title":{"rendered":"Python Ebooks maker &#8211; 4 &#8211; save files"},"content":{"rendered":"<p>Today we are going to add a button to the GUI to save the text we changed in the files that we could just read previously. It is a very basic and rough way to do it, but it&#8217;s a start that we are going to make better in the next versions of this app to read and write ebook made by us with the app itself. Let&#8217;s see the changes in the code and go in the previous posts if you did not read them and you want to know how we get here.<\/p>\n<h2>A button to save the files<\/h2>\n<p>We are going to put, right before the listbox &#8211; in the <strong>__init__<\/strong> method of the class <strong>Ebook<\/strong>, with the file names on the left (the menu), a <strong>button<\/strong> with this text: &#8220;Save&#8221;, to save the change you made in the files.<\/p>\n<pre class=\"lang:default decode:true \">\t\tself.button = tk.Button(self.frame1, text=\"Save\", command = self.save)\r\n\t\tself.button.pack()<\/pre>\n<p>Here it is:<\/p>\n<figure id=\"attachment_3580\" aria-describedby=\"caption-attachment-3580\" style=\"width: 599px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/save.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3580 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/save.png\" alt=\"\" width=\"599\" height=\"136\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/save.png 599w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/save-320x73.png 320w\" sizes=\"auto, (max-width: 599px) 100vw, 599px\" \/><\/a><figcaption id=\"caption-attachment-3580\" class=\"wp-caption-text\">The save button<\/figcaption><\/figure>\n<h2>The save method<\/h2>\n<p>This button, on click, calls the save method in the Ebook class:<\/p>\n<pre class=\"lang:default decode:true \">\tdef save(self):\r\n\t\twith open(self.filename, \"w\") as file:\r\n\t\t\tfile.write(self.text.get(\"1.0\", tk.END))<\/pre>\n<p>As you can see we have the self.filename attribute. We created it into the\u00a0<strong>show_text\u00a0<\/strong>function substituting the local variable filename with self.filename, so that it is now avaiable in all the class.<\/p>\n<pre class=\"lang:default decode:true\">\t\t\tself.filename = self.lstb.get(index)\r\n\t\t\twith open(self.filename) as file:<\/pre>\n<p>Another little change in the show_text method it to make run its code only to this condition:<\/p>\n<pre class=\"lang:default decode:true \">\t\tif not self.lstb.curselection() is ():<\/pre>\n<p>I needed to put this, because when you select something in the text editor, the app loses the selection in the listbox, so that, due to the bind to selection in the listbox, the <strong>index = self.lstb.curselection()[0]<\/strong> gives an error, even if the program does not crash, that is annoying. So, with that condition, if the listbox is not selected, it does nothing, not causing any error.<\/p>\n<h2>The whole code to save files<\/h2>\n<p>So, it is just with a couple of lines of code and some adjustment that now we are finally able to change our files that are present in the folder lezioni (or whatever name you choose for it).<\/p>\n<pre class=\"lang:default decode:true \">import tkinter as tk\r\nimport glob\r\n\r\n\r\nclass Ebook:\r\n\tdef __init__(self, root):\r\n\t\t\"\"\"Define window for the app\"\"\"\r\n\t\tself.root = root\r\n\t\tself.root.geometry(\"600x400\")\r\n\t\tself.root[\"bg\"] = \"coral\"\r\n\t\tself.menu()\r\n\t\tself.editor()\r\n\r\n\t# Widgets on the left ===============|\r\n\tdef menu(self):\r\n\t\t\"\"\"Listbox on the left with file names\"\"\"\r\n\t\tself.frame1 = tk.Frame(self.root)\r\n\t\tself.frame1[\"bg\"] = \"coral\"\r\n\t\tself.frame1.pack(side='left', fill=tk.Y)\r\n\t\tself.button = tk.Button(self.frame1, text=\"Save\", command = self.save)\r\n\t\tself.button.pack()\r\n\t\tself.lstb = tk.Listbox(self.frame1, width=30)\r\n\t\tself.lstb['bg'] = \"black\"\r\n\t\tself.lstb['fg'] = 'gold'\r\n\t\tself.lstb.pack(fill=tk.Y, expand=1)\r\n\t\t# ========= insert files name ==========\r\n\t\tfiles = glob.glob(\"lezioni\\\\*.txt\")\r\n\t\tprint(files)\r\n\t\tfor file in files:\r\n\t\t\tself.lstb.insert(tk.END, file)\r\n\t\t# ===== show text on select ============\r\n\t\tself.lstb.bind(\"&lt;&lt;ListboxSelect&gt;&gt;\", lambda x: self.show_text_in_editor())\r\n\r\n\tdef save(self):\r\n\t\twith open(self.filename, \"w\") as file:\r\n\t\t\tfile.write(self.text.get(\"1.0\", tk.END))\r\n\r\n\r\n\tdef show_text_in_editor(self):\r\n\t\t\"\"\"Shows text of selected file in the editor\"\"\"\r\n\t\tif not self.lstb.curselection() is ():\r\n\t\t\tindex = self.lstb.curselection()[0]\r\n\t\t\tself.filename = self.lstb.get(index)\r\n\t\t\twith open(self.filename) as file:\r\n\t\t\t\tcontent = file.read()\r\n\t\t\tself.text.delete(\"1.0\", tk.END)\r\n\t\t\tself.text.insert(tk.END, content)\r\n\r\n\tdef editor(self):\r\n\t\t\"\"\"The text where you can write\"\"\"\r\n\t\tself.text = tk.Text(self.root)\r\n\t\tself.text['bg'] = \"darkgreen\"\r\n\t\tself.text['fg'] = 'white'\r\n\t\tself.text['font'] = \"Arial 24\"\r\n\t\tself.text.pack(fill=tk.Y, expand=1)\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\troot = tk.Tk()\r\n\tapp = Ebook(root)\r\n\tapp.root.title(\"Lezioni\")\r\n\troot.mainloop()<\/pre>\n<h2>Live coding video<\/h2>\n<p>The live coding video shows you the save method adding.<\/p>\n<p><iframe loading=\"lazy\" title=\"Python ebook maker 3 - Save files\" width=\"747\" height=\"420\" src=\"https:\/\/www.youtube.com\/embed\/WXnFwbsuOyU?feature=oembed&amp;enablejsapi=1\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h2>What next?<\/h2>\n<p>Now we need to create new files from the app, even if we can do it manually saving them in the folder, but it is annoying, so&#8230; see ya in the next post.<\/p>\n","protected":false},"excerpt":{"rendered":"Save files you changed in the app to make ebooks with Python and tkinter\n<a class=\"moretag\" href=\"https:\/\/pythonprogramming.altervista.org\/python-ebooks-maker-4-save-files\/\"> [...]<\/a>","protected":false},"author":1,"featured_media":3583,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[551,1,49],"tags":[553,552,4,51],"class_list":["post-3579","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ebooks","category-examples","category-tkinter","tag-ebook","tag-ebooks","tag-python","tag-tkinter"],"avopt_banners_inside_post":true,"avopt_banners_on_page":true,"av_copy_from":"","av_sharing_message":"","av_sharing_allowed":false,"av_sharing_on":{"fb":[],"tw":[]},"av_allow_affiliate_banner":false,"av_allow_affiliate_multi_banner":false,"av_show_affiliation_buy_button":false,"av_post_rating":true,"av_have_post_rating_value":false,"av_is_artificial_intelligence_content":false,"_links":{"self":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3579","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/comments?post=3579"}],"version-history":[{"count":2,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3579\/revisions"}],"predecessor-version":[{"id":3584,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3579\/revisions\/3584"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media\/3583"}],"wp:attachment":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media?parent=3579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/categories?post=3579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/tags?post=3579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}