{"id":3335,"date":"2019-09-04T08:35:20","date_gmt":"2019-09-04T06:35:20","guid":{"rendered":"https:\/\/pythonprogramming.altervista.org\/?p=3335"},"modified":"2019-11-13T18:09:33","modified_gmt":"2019-11-13T17:09:33","slug":"python-sqlite3-part-3-reoganizing-the-code","status":"publish","type":"post","link":"https:\/\/pythonprogramming.altervista.org\/python-sqlite3-part-3-reoganizing-the-code\/","title":{"rendered":"Python sqlite3 &#8211; part. 3: reoganizing the code"},"content":{"rendered":"<p>Let&#8217;s continue out example of possible use of <strong>sqlite3<\/strong> (database module) for <strong>Python<\/strong>. We created this GUI for our database with <strong>tkinter<\/strong> to show the basic use of both module, sqlite3 and tkinter. We added some <strong>widgets<\/strong> and some basic functions to create a database and a <strong>table<\/strong>. Now we want to make the <strong>GUI<\/strong> more clear and add some features like adding values. To see the table in the database you can use this <strong>free software<\/strong> <a href=\"https:\/\/sqlitebrowser.org\/\">DB Browser for Sqlite<\/a>.<\/p>\n<p><a href=\"https:\/\/sqlitebrowser.org\/\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/avatars1.githubusercontent.com\/u\/7454271?s=400&amp;v=4\" alt=\"Risultati immagini per db browser for sqlite\" width=\"128\" height=\"128\" \/><\/a><\/p>\n<h2>Video about the app until now<\/h2>\n<p>Click on the arrow in the middle to start the video with the way the app works explained.<\/p>\n<div style=\"width: 300px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-3335-1\" width=\"300\" height=\"500\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/sqlite3_3.mp4?_=1\" \/><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/sqlite3_3.mp4\">https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/sqlite3_3.mp4<\/a><\/video><\/div>\n<p>&nbsp;<\/p>\n<h2>Let&#8217;s re-organize our code<\/h2>\n<p>We want to get back and remake our code so that we can have different windows for different funtions, so that it is easier to manage the program.<\/p>\n<p>This is the code for the main window, the menu window<\/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    def __init__(self, root):\r\n        self.root = root\r\n        self.root.geometry(\"300x100\")\r\n        self.root['bg'] = \"cyan\"\r\n        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()\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\nroot = tk.Tk()\r\nwin = App(root)\r\nroot.mainloop()<\/pre>\n<p>This is the output until now<\/p>\n<p><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/window_menu.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3347 aligncenter\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/window_menu.jpg\" alt=\"\" width=\"302\" height=\"132\" \/><\/a><\/p>\n<h2>The App class code video<\/h2>\n<p>This is the video of the live coding of the menu window (see the code above) that will call the other 2 windows:<\/p>\n<p><iframe loading=\"lazy\" title=\"Python 'n Sqlite 3.1 - Menu window\" width=\"747\" height=\"420\" src=\"https:\/\/www.youtube.com\/embed\/_e-eYuXw8-Y?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<p><strong>To be continued&#8230; ?<\/strong><\/p>\n<p>This is the final <strong>output<\/strong>&#8230;<\/p>\n<p><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win_3_3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3355 aligncenter\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win_3_3.png\" alt=\"\" width=\"531\" height=\"513\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win_3_3.png 531w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/win_3_3-320x309.png 320w\" sizes=\"auto, (max-width: 531px) 100vw, 531px\" \/><\/a><\/p>\n<h2>The whole code<\/h2>\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\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        self.butnew(\"Create Database\", Win1)\r\n        self.butnew(\"Create Table\", Win2)\r\n\r\n    def butnew(self, text, _class):\r\n        \"\"\"Create a new button with text and class as argument\"\"\"\r\n        tk.Button(\r\n            self.root, text=text,\r\n            command=lambda: self.new_window(_class)).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 = []\r\n\r\n    def show_db(self):\r\n        for file in glob(\"*.db\"):\r\n            self.lb.insert(tk.END, file)\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\n    def mk_tb(self, dbn, tbn):\r\n        self.conn = lite.connect(dbn.get())\r\n        self.cur = self.conn.cursor()\r\n        Win.fields = \"\".join(Win.fields)\r\n        self.cur.execute(\"\"\"create table {} (\r\n        {} );\"\"\".format(tbn, Win.fields))\r\n        Win.fields = []\r\n        self.conn.close()\r\n\r\n    def mk_fl(self):\r\n        Win.fields.append(self.efl.get())\r\n        self.vfl.set(\"\")\r\n\r\n    def show_selection(self):\r\n        x = self.lb.curselection()[0]\r\n        x = self.lb.get(x)\r\n        self.dbn.set(x)\r\n\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['bg'] = \"pink\"\r\n        self.label()\r\n        self.entry()\r\n        self.button()\r\n        self.listbox()\r\n\r\n    def label(self):\r\n        self.label = tk.Label(self.root, text=\"Create a db [insert the name]\")\r\n        self.label.pack()\r\n\r\n    def entry(self):\r\n        self.db = tk.StringVar()\r\n        self.e = tk.Entry(self.root, textvariable=self.db)\r\n        self.e.pack()\r\n\r\n    def button(self):\r\n        \"\"\"Create db\"\"\"\r\n        self.b = tk.Button(\r\n            self.root, text=\"Create DB\", command=lambda: self.mk_db())\r\n        self.b.pack()\r\n\r\n    def db_name_widgets(self):\r\n        # label and Entry for Database name\r\n        self.ldbname = tk.Label(self.root, text=\"Insert Database name\")\r\n        self.ldbname.pack()\r\n        self.dbn = tk.StringVar()\r\n        self.edb = tk.Entry(self.root, textvariable=self.dbn)\r\n        self.edb.pack()\r\n\r\n    def listbox(self):\r\n        self.lb = tk.Listbox(self.root)\r\n        self.lb.pack()\r\n        self.show_db()\r\n        self.lb.bind(\"&lt;Double-Button&gt;\", lambda x: self.show_selection())\r\n\r\n\r\nclass Win2(Win):\r\n    def __init__(self, root):\r\n        Win.__init__(self)\r\n        self.root = root\r\n        self.root.geometry(\"400x500\")\r\n        self.root['bg'] = \"green\"\r\n        self.listbox()\r\n        self.db_name_widgets()\r\n        self.tb_name_widgets()\r\n        self.fields_widgets()\r\n        self.btn_create_table()\r\n\r\n    def db_name_widgets(self):\r\n        # label and Entry for Database name\r\n        self.ldbname = tk.Label(\r\n            self.root, text=\"Insert Database name\")\r\n        self.ldbname.pack()\r\n        self.dbn = tk.StringVar()\r\n        self.edb = tk.Entry(\r\n            self.root, textvariable=self.dbn)\r\n        self.edb.pack()\r\n\r\n    def listbox(self):\r\n        self.lb = tk.Listbox(self.root)\r\n        self.lb.pack()\r\n        self.show_db()\r\n        self.lb.bind(\"&lt;Double-Button&gt;\", lambda x: self.show_selection())\r\n\r\n    def tb_name_widgets(self):\r\n        self.ltbname = tk.Label(self.root, text=\"Insert Table name\")\r\n        self.ltbname.pack()\r\n        self.tbn = tk.StringVar()\r\n        self.etb = tk.Entry(self.root, textvariable=self.tbn)\r\n        self.etb.pack()\r\n\r\n    def fields_widgets(self):\r\n        self.lflname = tk.Label(self.root, text=\"\"\"Insert Fields (2 at\r\nleast) name and type\\n followeb by a comma, one by one,\r\n\\nclicking once for\r\neach field\\nThe last field must be without comma\r\n\\nExample:\\nid integer,\"\"\")\r\n        self.lflname.pack()\r\n        self.vfl = tk.StringVar()\r\n        self.efl = tk.Entry(self.root, textvariable=self.vfl)\r\n        self.efl.pack()\r\n        self.bfl = tk.Button(\r\n            self.root, text=\"Create Field\", command=lambda: self.mk_fl())\r\n\r\n        self.bfl.pack()\r\n\r\n    def btn_create_table(self):\r\n        self.btb = tk.Button(\r\n            self.root, text=\"Create Table\",\r\n            command=lambda: self.mk_tb(self.dbn, self.tbn))\r\n        self.btb.pack()\r\n\r\n\r\nroot = tk.Tk()\r\nwin = App(root)\r\nroot.mainloop()\r\n<\/pre>\n<p>The pdf with the code: <a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/DBManager.pdf\">DBManager<\/a><\/p>\n<h2>How the windows looks now<\/h2>\n<p>In this short video you can see the three windows in with the widgets are divided now, to make the program more easy to manage and visually more intuitive than it was before, before we add other widgets in another window to add our data.<\/p>\n<div style=\"width: 747px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-3335-2\" width=\"747\" height=\"420\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/output8.mp4?_=2\" \/><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/output8.mp4\">https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/09\/output8.mp4<\/a><\/video><\/div>\n<p>Next time we will make a better look for this application. Now it&#8217;s a little messy.<\/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","protected":false},"excerpt":{"rendered":"Let&#8217;s reorganize the code of te sqlite3 + tkinter code we made in two previous lessons. We are going to use different windows.\n<a class=\"moretag\" href=\"https:\/\/pythonprogramming.altervista.org\/python-sqlite3-part-3-reoganizing-the-code\/\"> [...]<\/a>","protected":false},"author":1,"featured_media":3352,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[1,480,481],"tags":[239,530,52,4,531,499,485,529,51],"class_list":["post-3335","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-examples","category-sqlite","category-sqlite3","tag-database","tag-fields","tag-gui","tag-python","tag-records","tag-sql","tag-sqlite3","tag-tables","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\/3335","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=3335"}],"version-history":[{"count":18,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3335\/revisions"}],"predecessor-version":[{"id":4144,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3335\/revisions\/4144"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media\/3352"}],"wp:attachment":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media?parent=3335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/categories?post=3335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/tags?post=3335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}