{"id":3364,"date":"2019-09-05T07:18:24","date_gmt":"2019-09-05T05:18:24","guid":{"rendered":"https:\/\/pythonprogramming.altervista.org\/?p=3364"},"modified":"2019-09-06T07:10:53","modified_gmt":"2019-09-06T05:10:53","slug":"sqlite-and-python-part-3-2","status":"publish","type":"post","link":"https:\/\/pythonprogramming.altervista.org\/sqlite-and-python-part-3-2\/","title":{"rendered":"Sqlite and Python &#8211; part 3.2"},"content":{"rendered":"<p>I am goint to <strong>reorganize<\/strong> the code to use tkinter and sqlite using different <strong>windows<\/strong> made with <strong>tkinter<\/strong> for our program made with sqlite3 module in <strong>Python<\/strong> programming language to create a <strong>database<\/strong>&#8230; We are going to understand how to split the code into 4 different <strong>classes<\/strong>, so that we can have a clear understanding of who does what, when we will add other features to the program.<\/p>\n<h2>The new code<\/h2>\n<p>Last time we <strong>explained<\/strong> the menu window code you can see below:<\/p>\n<pre class=\"lang:default decode:true\">import sqlite3 as lite\r\nfrom sqlite3 import Error\r\nimport tkinter as tk\r\nfrom glob import glob\r\n\r\nclass App:\r\n    # window\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"200x200\")\r\n        self.root['bg'] = \"cyan\"\r\n        tk.Button(self.root, text = \"Create a database\",\r\n            command= lambda: self.new_window(Win1)).pack()\r\n        tk.Button(self.root, text = \"Create a table\",\r\n            command= lambda: self.new_window(Win2)).pack()\r\n    \r\n    def new_window(self, _class):\r\n        self.new = tk.Toplevel(self.root)\r\n        _class(self.new)<\/pre>\n<p>I deleted the <strong>new_button<\/strong> function, as you can see in the video, because I thought it was nice but a little redundant, so, I prefer a little less code, even if it is a little less readable at first glance, but with the practice we won&#8217;t notice too much difference. If you want, you can always leave it like it was. See the code below to notice the difference and choose the best for you, it&#8217;s a matter of taste, after all.<\/p>\n<pre class=\"lang:default decode:true \">        self.butnew(\"Create Database\", Win1)\r\n        self.butnew(\"Create Table\", Win2)\r\n\r\n    def butnew(self, text, _class):\r\n        tk.Button(self.root, text = text, command= lambda: self.new_window(_class)).pack()<\/pre>\n<p>Now it is:<\/p>\n<pre class=\"lang:default decode:true \">        tk.Button(self.root, text = \"Create a database\",\r\n            command= lambda: self.new_window(Win1)).pack()\r\n        tk.Button(self.root, text = \"Create a table\",\r\n            command= lambda: self.new_window(Win2)).pack()<\/pre>\n<p>2 lines (splitted in 2) instead of 4 lines, wich one do you prefer? I like the first neat version, but the second avoids a method, so&#8230; let&#8217;s go on.<\/p>\n<figure id=\"attachment_3369\" aria-describedby=\"caption-attachment-3369\" style=\"width: 202px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3369 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win.jpg\" alt=\"\" width=\"202\" height=\"232\" \/><\/a><figcaption id=\"caption-attachment-3369\" class=\"wp-caption-text\">The menu window<\/figcaption><\/figure>\n<h2>The mother of the new windows (super class)<\/h2>\n<p>In this class I want to put the common code that will be <strong>inherited<\/strong> by the other windows. For example we will put the listbox with the list of the database file that we create here, because we will use in window 1 and window 2 (<strong>Win1<\/strong> and <strong>Win2<\/strong> classes).<\/p>\n<pre class=\"lang:default decode:true\">class Win:\r\n    fields = [] # To create the records field in the databases table\r\n    def listbox(self):\r\n        self.lab_lb = tk.Label(self.root, text=\"Database in the folder\")\r\n        self.lab_lb.pack()\r\n        self.lb = tk.Listbox(self.root) # create a listbox\r\n        self.lb.pack()                  # make it visible\r\n        for file in glob(\"*.db\"):       # insert all the db file in the listbox\r\n            self.lb.insert(tk.END, file)<\/pre>\n<p>So, this class does nothing except contain the common attributes and methods of the windows.<\/p>\n<h2>Win1<\/h2>\n<p>Let&#8217;s see the <strong>Win1<\/strong>, to create the database:<\/p>\n<pre class=\"lang:default decode:true\">class Win1(Win):\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"400x300\")\r\n        self.root.title(\"Create Database\")\r\n        self.widgets_db() # widgets to create the new db\r\n        self.listbox()\r\n\r\n    def widgets_db(self):\r\n        \"\"\"Widgets to create a new database\r\n\r\n            - a label \"Create a db\" ........ self.l\r\n            - an entry ..................... self.e \r\n            - a button ..................... self.b\r\n        \r\n        \"\"\"\r\n        self.l = tk.Label(self.root, text=\"Create a db [insert the name]\")\r\n        self.l.pack()\r\n        self.db = tk.StringVar()\r\n        self.e = tk.Entry(self.root, textvariable = self.db)\r\n        self.e.pack()\r\n        self.b = tk.Button(self.root, text=\"Create DB\", command= lambda: self.mk_db())\r\n        self.b.pack()<\/pre>\n<p>As you can see, this uses the <strong>listbox<\/strong> method of the super class <strong>Win<\/strong> and adds her own widgets to create the database (a label, an entry and a button).<\/p>\n<figure id=\"attachment_3377\" aria-describedby=\"caption-attachment-3377\" style=\"width: 385px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/button_mk_db.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3377 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/button_mk_db.png\" alt=\"\" width=\"385\" height=\"302\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/button_mk_db.png 385w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/button_mk_db-320x251.png 320w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/button_mk_db-280x220.png 280w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/><\/a><figcaption id=\"caption-attachment-3377\" class=\"wp-caption-text\">The clicking the button creates the database and insert its name in the listbox with the method mk_db<\/figcaption><\/figure>\n<p>We also need a <strong>method<\/strong> to create the database, that is the following one <strong>mk_db<\/strong> and it is used only in this window, so we add it to the <strong>Win1<\/strong> class:<\/p>\n<pre class=\"lang:default decode:true\">    def mk_db(self):\r\n        db = self.e.get()\r\n        if db.endswith(\".db\"):\r\n            pass\r\n        else:\r\n            db = db + \".db\"\r\n        try:\r\n            conn = lite.connect(db)\r\n            if db in self.lb.get(0, tk.END):\r\n                pass\r\n            else:\r\n                self.lb.insert(tk.END, db)\r\n            return conn\r\n        except Error as e:\r\n            print(e)\r\n        finally:\r\n            self.db.set(\"\")\r\n            conn.close()<\/pre>\n<p>Whatch the video to see how it works. There are a lot of lines, but it does a few basic things.<\/p>\n<figure id=\"attachment_3370\" aria-describedby=\"caption-attachment-3370\" style=\"width: 402px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3370 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win1.jpg\" alt=\"\" width=\"402\" height=\"332\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win1.jpg 402w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win1-320x264.jpg 320w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><\/a><figcaption id=\"caption-attachment-3370\" class=\"wp-caption-text\">The window to create databases<\/figcaption><\/figure>\n<h2>Win2<\/h2>\n<p>This is the second window. Until now it just has the <strong>listbox<\/strong> with the list of the database. So we do not need to write again the code for the listbox, we just need to call the method that has been inherited.<\/p>\n<pre class=\"lang:default decode:true\">class Win2(Win):\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"400x500\")\r\n        self.root.title(\"Create Tables\")\r\n        self.listbox()<\/pre>\n<p>There it is, just a listbox.<\/p>\n<figure id=\"attachment_3371\" aria-describedby=\"caption-attachment-3371\" style=\"width: 402px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3371 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win2.jpg\" alt=\"\" width=\"402\" height=\"532\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win2.jpg 402w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win2-320x423.jpg 320w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><\/a><figcaption id=\"caption-attachment-3371\" class=\"wp-caption-text\">The second window, inclomplete until now, to create tables<\/figcaption><\/figure>\n<p>At the end, out of the classes there is the code to start it all, making the main window and istanciating the App class.<\/p>\n<pre class=\"lang:default decode:true\">root = tk.Tk()\r\napp = App(root)\r\nroot.mainloop()<\/pre>\n<h2>The video with the live coding of the app until now<\/h2>\n<p><iframe loading=\"lazy\" title=\"Sqlite and Python - part 3.2\" width=\"747\" height=\"420\" src=\"https:\/\/www.youtube.com\/embed\/LzI5hF5VIRE?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>The whole code &#8217;til now<\/h2>\n<p>This is the re-roganized code until now&#8230; we will continue in the next post.<\/p>\n<pre class=\"lang:default decode:true \">import sqlite3 as lite\r\nfrom sqlite3 import Error\r\nimport tkinter as tk\r\nfrom glob import glob\r\n\r\nclass App:\r\n    # window\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"200x200\")\r\n        self.root['bg'] = \"cyan\"\r\n        tk.Button(self.root, text = \"Create a database\",\r\n            command= lambda: self.new_window(Win1)).pack()\r\n        tk.Button(self.root, text = \"Create a table\",\r\n            command= lambda: self.new_window(Win2)).pack()\r\n    \r\n    def new_window(self, _class):\r\n        self.new = tk.Toplevel(self.root)\r\n        _class(self.new)\r\n\r\n\r\nclass Win:\r\n    fields = [] # To create the records field in the databases table\r\n    def listbox(self):\r\n        self.lab_lb = tk.Label(self.root, text=\"Database in the folder\")\r\n        self.lab_lb.pack()\r\n        self.lb = tk.Listbox(self.root) # create a listbox\r\n        self.lb.pack()                  # make it visible\r\n        for file in glob(\"*.db\"):       # insert all the db file in the listbox\r\n            self.lb.insert(tk.END, file)\r\n\r\nclass Win1(Win):\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"400x300\")\r\n        self.root.title(\"Create Database\")\r\n        self.widgets_db() # widgets to create the new db\r\n        self.listbox()\r\n\r\n    def widgets_db(self):\r\n        \"\"\"Widgets to create a new database\r\n\r\n            - a label \"Create a db\" ........ self.l\r\n            - an entry ..................... self.e \r\n            - a button ..................... self.b\r\n        \r\n        \"\"\"\r\n        self.l = tk.Label(self.root, text=\"Create a db [insert the name]\")\r\n        self.l.pack()\r\n        self.db = tk.StringVar()\r\n        self.e = tk.Entry(self.root, textvariable = self.db)\r\n        self.e.pack()\r\n        self.b = tk.Button(self.root, text=\"Create DB\", command= lambda: self.mk_db())\r\n        self.b.pack()\r\n\r\n    def mk_db(self):\r\n        db = self.e.get()\r\n        if db.endswith(\".db\"):\r\n            pass\r\n        else:\r\n            db = db + \".db\"\r\n        try:\r\n            conn = lite.connect(db)\r\n            if db in self.lb.get(0, tk.END):\r\n                pass\r\n            else:\r\n                self.lb.insert(tk.END, db)\r\n            return conn\r\n        except Error as e:\r\n            print(e)\r\n        finally:\r\n            self.db.set(\"\")\r\n            conn.close()\r\n\r\nclass Win2(Win):\r\n    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"400x500\")\r\n        self.root.title(\"Create Tables\")\r\n        self.listbox()\r\n\r\nroot = tk.Tk()\r\napp = App(root)\r\nroot.mainloop()<\/pre>\n<p>To be continued&#8230;<\/p>\n<script>\r\nlet title = \"SqLite3 & Python\"\r\n\tlet links = [\r\n[\"https:\/\/pythonprogramming.altervista.org\/python-and-sqlite-basics\/\",\"Sqlite3 Basic 1\"],\r\n[\"https:\/\/pythonprogramming.altervista.org\/python-and-sqlite-with-tkinter-part-1\/\",\"Sqlite3 - part 1\"],\r\n[\"https:\/\/pythonprogramming.altervista.org\/sqlite3-tkinter-part-ii\/\",\"Sqlite3 - part 2\"],\r\n[\"https:\/\/pythonprogramming.altervista.org\/python-sqlite3-part-3-reoganizing-the-code\/\",\"Sqlite3 - part 3.1\"],\r\n[\"https:\/\/pythonprogramming.altervista.org\/sqlite-and-python-part-3-2\/\",\"Sqlite3 - part 3.2\"],\r\n[\"https:\/\/pythonprogramming.altervista.org\/sqlite-and-tkinter-in-python-part-3-3\/\",\"Sqlite3 - part 3.3\"]\r\n\t];\r\n<\/script>\r\n<script>\r\n\t\r\nif (typeof next2 != \"undefined\"){let next2 = 0;}\r\n\t\r\nnext2 = 0;\r\n\thtml = \"\";\/\/<b style='color:coral;font-size:1.2em'>Other posts about \" + title + \"<\/b><br>\";\r\nfor (address of links) \r\n{\r\n\r\n\tif (next2 == 1){\r\n\t\thtml += \"<div style='background:coral'>\";\r\n\t\thtml += \"Next link => <a href='\" + address[0] + \"'>\" + address[1] + \"<\/a>\";\r\n\t\thtml += \"<\/div><br>\";\r\n\t\tnext2 = 0;\r\n\t}\r\n\tif (address[0] == document.URL) {\r\n\t\tnext2 = 1;\r\n\t}\r\n}\r\n\r\nif (typeof next != \"undefined\") {let next = 0;}\r\nif (typeof addressStart != \"undefined\") {let addressStart = \"\";}\r\nnext = 0;\r\naddressStart = \"<a href='\";\r\nfor (address of links) {\r\n\tif (next == 1){\r\n\t\thtml += \">>>\" + addressStart + address[0] + \"'>\" + address[1] + \"<\/a><br>\";\r\n\t\tnext = 0;\r\n\t}\r\n\telse if (addressStart + address[0] != document.URL)\r\n\t{\r\n\t\thtml += addressStart + address[0] + \"'>\" + address[1] + \"<\/a><br>\";\r\n\t}\r\n\telse\r\n\t{\r\n\t\tnext = 1;\r\n\t\tnext_address = address[0]\r\n\t\tnext_title = address[1]\r\n\t\thtml += \"<span style='color:gray'>\" + address[1] + \"<\/span><br>\";\r\n\t}\r\n\r\n}\r\n\r\n\thtml += `<span style=\"font-size:8px\">Powered by <a href=\"https:\/\/pythonprogramming.altervista.org\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2673\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/06\/altervista2.png\" alt=\"\" width=\"70\" height=\"25\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/06\/altervista2.png 156w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/06\/altervista2-150x56.png 150w\" sizes=\"auto, (max-width: 70px) 100vw, 70px\" \/>pythonprogramming.altervista.org<\/a><\/span>`\r\n\thtml = \"<div style='background:yellow'>\" + html + \"<\/div>\";\r\n\tdocument.write(html)\r\n<\/script>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"Sqlite and tkinter part 3.2 to make 2 windows to control the database\n<a class=\"moretag\" href=\"https:\/\/pythonprogramming.altervista.org\/sqlite-and-python-part-3-2\/\"> [...]<\/a>","protected":false},"author":1,"featured_media":3365,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[479,480,481,49,484],"tags":[532,4,485,51],"class_list":["post-3364","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-database","category-sqlite","category-sqlite3","category-tkinter","category-tkinter-and-sqlite3","tag-databases","tag-python","tag-sqlite3","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\/3364","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=3364"}],"version-history":[{"count":8,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3364\/revisions"}],"predecessor-version":[{"id":3379,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3364\/revisions\/3379"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media\/3365"}],"wp:attachment":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media?parent=3364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/categories?post=3364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/tags?post=3364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}