Create GUI App with Tkinter and SQLite - Step by Step Python Tutorial for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone today we'll create an extremely beautiful kinter application and no i'm not confused i really mean tinter even though it is notorious for not being beautiful today we will force it now another cool thing on the menu is we will connect an sqlite database to our application which will make it much more sophisticated and yet 100 beginner friendly and we will begin by downloading the starter files of this project which you can of course find on my github account and the link is in the description now inside those files you will find two different logos you will also find one database file as well as two truetype font files now in addition you can also access the wireframe of this project which is basically a rough estimate of how our application will look like now in my case this would be frame number one and this would be frame number two and then last but not least we also have our python file which we will access with our favorite ide or text editor in my case sublime and we can see that this file contains only the most basic commands to run a kinter application so first we import kinter as tk then we initialize a window object and we call it root and then lastly we are calling the main loop method which basically displays our window up until we click on the exit button cool now let's quickly see everything in action and for this we will need a terminal in my case i'm using anaconda now if you're not sure how or why i'm using anaconda please check out my awesome tutorial on the topic which will get you up to speed and this is really good especially if you're new to this now the first thing we'll do is we will activate our working environment in my case it is called n39 next we will navigate to the project folder so let's go ahead and copy this path and let's paste it back in our terminal following a cd command as in change sorry my cat just jumped near ah come on now once we have removed our cat from the table we will press enter and beautiful we are inside the project folder now from here we will run our application with python recipe picker dot py which is the name of our python file and we will then press enter once we do so we have an empty tinter window popping at the very top left of our screen and only after we click on the exit button this application collapses awesome now let's make a few basic adjustments to this window object now the first thing i'd like to do is i would like to give it a title so we will type root dot title where we can specify a string of our choice in my case i'm gonna go for recipe picker next let's make sure we are displaying our application at the very center of the screen and not at the top left corner to do so we will type root and we will call the eval method on it now the eval method allows us to write commands in another programming language called tcl luckily tcl is very simple and it goes as follows we will open a set of quotes where we will type tk as in kinter followed by a double colon which allows us to fetch the place window method next we will specify a dot which represents the top level window and we will place it and this at the center now if we save everything and we run this code we will simply press on the up arrow which will fetch our most recent command and we will hit enter beautiful our application pops at the center of the screen and we can see the beginning of the title which is not exactly what we're aiming for because we'd like to see the entire title right we would like this window to be much bigger so let's take care of that now one way we can do this is by creating something called a frame widget where its main purpose is to group all kinds of elements together so we can imagine frames as different pages in the same application so let's go ahead and create our very first frame with tk.frame with a capital f where the first argument would be the root window the next argument would be the width which we will set to 500 pixels next we will set the height to 600 and if we're already here we might as well set the background color as well that's why we will type bg and we will set it to a hashtag 3d6466 which should result in a teal color if i didn't mess anything up now let's go ahead and assign this expression to frame one and we will also need to call the grid method on this frame in order to place it on the page so let's go ahead and type frame 1 dot grid and we will place it at row 0 and at column 0. now i know that these two values are the default values but here's the thing about kinter we still need to specify them otherwise we might get unexpected results that's just skin term it is what it is now let's go ahead and save everything and let's see if it worked beautiful our window is much bigger now and i didn't mess up the teal color awesome now the only problem is because i've zoomed in a lot on my end just so you guys can see the text much larger my window is now overhanging from the bottom of the screen so just for the sake of this tutorial i'm gonna slightly revise the logic behind my centering command and you don't need to do this on your end this is just something i'll do for myself now i have a feeling that some of you guys will find it very useful so let's quickly go over these commands so in the first line of code we are pulling the total width of the screen and we are dividing it by two which will place our window at the center next we are pulling the total height of the screen and we multiply it by 0.1 which will place our window 10 away from the top edge and then lastly i am calling the geometry method to set the size of the window as well as its location which we have generated from the above variables that's it now the reason why i don't want you to use those three lines of code is not because there's three of them as opposed to this one above but in general this is not the best approach if you're curious why please leave me a comment below or just keep watching you will see why now let's save everything and let's give it a quick run let's make sure that it works as expected awesome 10 away from the top edge and right at the center of the screen well slightly slightly to the right but that's okay cool now let's fill our empty frame with some widgets and we will begin with a logo now the logo is an image and in order to display images we will need to use an image library called pillow so from pill as in pillow we will import image tk with a capital i and a capital t very important then we will scroll below and we will load one of our logos with image tk dot photo image in camel case once again where we will set the file attribute to assets slash r recipe underscore logo dot png which is one of our logos now in particular i'm talking about this guy awesome now let's go ahead and assign this expression to logo image and now once we have a kinter image loaded we can then convert it into a widget now kinter doesn't really have a special widget for images so instead we are using the tk.label widget once again with a capital l now the first argument we specify here would be the location where we'd like to place this widget in our case frame 1 not the root window now the next argument would be the image itself and in our case that's logo image and yes it is very important for it to be a tinter image cool now let's go ahead and assign this expression to logo widget just so we make a distinction between the two now in the next line of code we will do something absolutely ridiculous that we cannot get away with tkintor kind of forces us to do so so we will access the image attribute of our logo widget by typing logo widget dot image and we will set it once again to logo underscore image and yes i know we've done it above here but kinter really insists on us to do this again and we're kind of hostage here so let's just do it now if we don't do this once again we will get very unexpected results and kinter will go buggy on us so yeah don't mess with kinter cool now the last thing left to do is to call the pack method on this logo widget so we will type logo widget once again dot pack and beautiful now if we save everything and we run this code we should see our logo on the window okay well the logo is here but where's our background color let's see if we can fix it very quickly let's go back to our code and we will simply add a bg attribute to our label widget actually i'll move it a bit away because my face is about to cover it okay and we will once again set it to the exact same teal color as our background hopefully this will do the trick let's save everything let's give it a run okay so our logo now has a background color but not the rest of our window how are we supposed to fix it one way we can solve it is to prevent the child label element from modifying the parent frame element and we can do this with the pack propagate method so we will type frame 1 dot pack propagate and we will set it to false let's go ahead and save this file let's rerun it and not only did we fix all our background issues but we have also centered our logo and the rest of the widgets on the page awesome now let's move on so first let's store our background color in a special variable called bg color that's because we are about to repeat this background color multiple times across our application and it's not an easy string to remember okay so let's just assign it now we will replace every instance of 3d6466 with bg color we'll do this in both places beautiful and now we can move on with our instructions widget now in order to place some text inside our window we will need to use the tk dot label now widget once again and we will once again place it inside frame one but instead of specifying an image this time we'll specify some text and in my case i will set it to ready for your random recipe question mark and actually let's span it across multiple lines of code because i have a feeling my head will block half of it so let's take care of it in advance now let's go ahead and set the background color to bg color and we'll also set the foreground color as in fg or the text color to white easy peasy now let's quickly talk about fonts the main purpose of kinter is to be consistent across different operating systems so it doesn't matter if you use linux windows or mac your application will look exactly the same that's why tinter has a special list of fonts it works with and all of them all of them are equally ugly okay now unfortunately if you are not using windows you are limited to this set of fonts only okay so what we will do is we will first design this application with those generic tinter fonts and at the very end of this video i will show you how to use costume phones instead and again this will only work for windows so i apologize in advance okay now at first we will set this font to a tuple of tk menu font and we will also give it the size of 14. now the last thing left to do is to call the pack method on this widget to organize it nicely inside the frame and we'll actually call the pack method on the rest of our widgets as well with the exclusion of our frames where we called the grid method so these are just two alternatives cool now let's save everything let's give it a run beautiful here's our label widgets our instructions for this application now let's go ahead and add the last widget of this page which is the button and this time we will create a tk dot button widget and we will place it inside frame one we will also give it the text of shuffle and we will set its font to a tuple of tk heading font in the size of 20. awesome now this time we'll go for a slightly darker teal background so we will set bg to hashtag 28.39 3 a hopefully these are hard to remember guys now next we will set the foreground color to white once again and now since this time we are dealing with a much more interactable widget it makes a lot of sense to change the core sort to a pointing hand every time we hover above this button to do so we will type coursor equals hand to now in addition we can also make it much more interactable than this we will simply set an active background color and we will set it to a very light teal color which is much easier to remember so this goes by hashtag baddie i bet you santa is not very impressed with this one now because it's a very light teal we will also need to change the font color so let's change the active foreground color to black just so we have some contrast now the last argument we need to specify here would be the command now the command is basically a function that runs every time we press on this button let's uh call it load frame two we haven't defined it yet but i already know we're going to call it that way so what happens if we leave this function as is let's test it so it's called the pack method on this button and let's see what happens if we create this load frame function at the very top of our code so we will use the def keyword we will paste this function name and we will then print hello maria and again this is just for testing purposes now let's run this code cool so we have our button here but we didn't really press on it and we already see our message printed in the terminal what okay but what if we press on the shuffle button nothing happens so it looks like if we just specify the function name it's not really attached to a click on the button event so let's quickly fix it and the way to do so is to add an anonymous function called lambda right in front of our load frame to function okay and this colon is also very important and now if we save everything and we run this code we no longer see this message printed in our terminal so it's already a good start let's click on the shuffle button beautiful here's our message and as many times as we click on the shuffle button our message is printed again and again awesome now the only thing left to do with this frame is to add a bit of margin or padding in between those two elements because we have so much room on the page and we're not you know and we're cluttering them up instead of allowing them some space so let's go back to our code and the place where we specify some margins or padding is inside the pack method because pack is organizing those elements inside the frame so inside pack we will type paddy as in padding y i believe and we'll set it to 20. that's it let's save it let's see if it worked beautiful we have a really nice gap in between our elements now so that's it we are done with frame one and we can finally continue with frame two so back in our code let's do some organizing first now since we have added this load frame to function it kind of makes sense to wrap our frame one widgets in their very own function as well that's why right above we will define load frame one beautiful next we will copy our entire list of widgets starting from the logo and down to the very button let's cut it and let's paste it inside our new function we will also fix this indentation and another thing which i almost forgot is to copy our pack propagate method as well actually cut it entirely and paste it at the very top of our function beautiful and now frame 1 is officially complete and now we can move on with frame 2. now the first thing we'll do in regards to frame two is defining it or initializing it because we haven't done it yet so we'll scroll down we will copy our frame one command which my head blocks as per tradition we will paste it below and we'll slightly adjust it so frame 1 turns to frame 2 and we'll also delete this width and height specification because we would like this frame to adjust to the size of its elements why because we will be fetching different recipes time and again and those recipes they have different lengths of title and they have different number of ingredients okay that's why we don't want to limit the size of our frame and actually if you're curious that's exactly why i'm not a big fan of this geometry method approach we are limiting the size of our window so back to frame two there are two approaches of putting it on the grid so we can either copy this line of code that's the lazy approach we can paste it below and we can adjust frame one to frame two and that's it but the elegant approach the not so lazy approach is to wrap them inside a for loop okay so let's just scroll a bit lower and for frame in a tuple of frame one and frame two we will then call the grid method on the iteration variable of frame there you go we can then get rid of those two lines of code from above beautiful it looks much more elegant for some people it's important now lastly before we are trying to run this code we please do not forget to call the load frame one function otherwise we're not going to have any elements on the page okay let's save everything and let's give it a run beautiful okay so our application looks good what happens when we press on the shuffle button awesome so we didn't mess up anything in our code and now it's much much more organized so now let's quickly take a look in the wireframe before we move on and actually if you're curious this is my pancakes recipe if you follow those ingredients your pancakes would be mwah amazing i guarantee now what we have here is we have a logo widget and we have a button widget which we are very familiar with we can just copy and paste them and slightly adjust them but the biggest problem here is how exactly do we fetch the title and the list of ingredients from our database so let's focus on that first to do this we will first import sqlite3 and we will then define a brand new function called fetch underscore db as in fetch from database now first things first we will need to establish a connection with our database file which you can find inside the starter files in the data folder and there you go that's recipes.db so to establish this connection we will type connection equals sqlite3.connect to which we will pass the path or data recipes.db beautiful now if you're not sure how to work with sqlite i have an amazing tutorial on the topic and i even have a follow-up tutorial showing you how you can web scrape your own databases with the help of sqlite and mechanical soup which is exactly what i've done to create this database okay now i'm assuming that you watched both so if you're looking for a detailed explanation please check out those tutorials if you're looking for a quick explanation that's exactly what you're going to get here now once we have established a connection with our database we will then need to create something called a course or object so we'll do this with corsor equals connection dot cursor beautiful and now we can call sql commands on this cursor so we will type coursor dot execute and inside those round brackets we can then pass commands in sql which is another language that is meant to communicate with databases now before we can pass any type of sql commands we will need to understand the structure of our database first and it goes as follows each recipe is stored in a separate table the title of the recipe is stored as the name of the table and each of the ingredients is stored as a row or a record this while the columns or fields of our database are id at index 0 which is basically a self incrementing primary key which we are not going to use so we simply don't care about it okay and right after we have the name of the ingredients at index one we have the quantity of the ingredients at index two and lastly we have the unit of measure of the ingredients at index three and this pretty much summarizes the entire architecture of our database now the biggest challenge is that usually when we execute sql commands we need to know the name of the table we are trying to access in advance in our case it's a bit problematic because we are looking to randomly access different tables time and again but luckily there exists a way to fetch all the table names of a database and pull them into our python file now is this the best approach probably not because we are wasting lots of resources a better approach would be pre-loading all our table names into a csv file and then we can access one record at a time instead of accessing all the table names at once so you must be wondering how come we're using a different approach for this well what i'm about to show you is extremely simple and not a lot of people know how to do this so it makes us very special and the sql command to select all the table names of a database is select all from sqlite underscore schema where type equals a string of table and we will finish this expression with a semicolon because sql is no python now once we have selected everything we need to select we will also need to fetch it that's why we will type coursor dot fetch all and an empty set of round brackets we will now assign this expression to all underscore tables and let's print the very first recipe name with print all tables in the index of zero awesome now the last thing we'll need to do here inside this fetch database function at least for now is to terminate this connection which we have established earlier that's why we will type connection dot close that's it now let's go ahead and call this fetch database function within our load frame 2 function so let's just paste it and let's get rid of the print statement from below because we have a different way of checking if things work let's save everything let's press on shuffle look at this we are fetching the very first recipe name which is a southwestern beef brisket 100 000 awesome now let's add a bit of randomness just so we can fetch different recipes time and again now we will use numpy for our randomness so from numpy we will import random and then right below our fetch all command we will create a new variable called idx as in index and we will assign it to random.rend int as in random integer and we would like this integer to be anywhere between zero and the length of our all tables list minus one and that's because the length function starts counting from one while everything else starts counting from zero so we need to accommodate that with a minus one in the very end and then once we are generating this random integer we can now print all tables in the index of idx instead and this will result in different recipes time and again so let's save everything awesome let's press on shuffle we have a fish burgers with fresh something we'll press shuffle again we have creoles delay holy smokes orange marmalade i can pronounce that awesome so now let's go ahead and access the ingredients of those tables so first we will create a new variable called table name which is actually given to us by index 1 of our print statement because index 0 just keeps storing the type of table we can verify that right above so what we're actually looking for would be index one so let's go back to our code and then our table name is given to us by all tables in the random index of idx in the field of one beautiful now once we have fetched the table name we can actually select all the ingredients from this table with corsor dot execute to which we will pass the sql command of select all from space to which we will concatenate the table name as well as a semicolon very important and actually let's make it consistent let's use a double quote for that sorry now once we have selected all those beautiful values we will also fetch them and we'll store them as ingredients which we will assign to course or fetch all of course then we will go ahead and print those ingredients along with the table name just to make sure that everything works let's save everything and let's give it a quick run let's shuffle ha look at that so everything works but before we can display those messy records inside frame two we will need to slightly pre-process them so what do i mean we will basically need to get rid of those six digits in the end of the title of our recipe and we will also need to add some spaces in between the words in terms of the ingredients we will convert them into a grammatically accurate string so we can then easily pull them into label widgets so what do i mean instead of having separate values for milk two and tablespoons we will convert it into a string of two tablespoons of milk okay makes a lot of sense so let's go back to our code and do just that so let's do the following let's get rid of those two print statements and let's return the table name as well as the ingredients and actually if we call this a table name we might as well call this table records it's a bit more accurate and sure once we convert those records into a nice string we can then call it ingredients but up until then these are just a bunch of messy records so now let's go ahead and copy this name and we will replace ingredients in our return statement as well and once we have a nice return statement we can then move on with defining a brand new function called pre process which of course takes in the table name as well as the table records as input now the first thing we'll do is we will slice off the numeric extension of our title so we will type table name we will open a set of square brackets where we will select all the characters up until the character at index -6 which is essentially removing the last six characters of our string we can then assign this to title and another thing we'll need to do is we will need to add some spaces in between the words now in our case it's extremely easy because each of our words starts with a capital letter so the logic behind the next commands would be detecting those capital letters and in case we find them we will then concatenate a space right in front of them now there are a few ways of doing so but my favorite way is using a list comprehension which is basically a fancy one-liner for loop so for our list comprehension we will need a set of square brackets where i will explain all the commands as we go so we begin with char if char is lower which means that if our character is lowercase we do not touch it we leave it as is however if it is not the case we will need an else clause so if our character is uppercase we will then concatenate a space character right in front of this character easy peasy now the last thing we will specify here is we would like to do this for all the characters in title beautiful now this is self-explanatory i believe now we can then go ahead and reassign it back to title beautiful but a funny thing will happen if we will try to print this title so let me show you let's print it and we'll then discuss the results now before we can do anything we'll need to call this preprocess function so let's just copy it let's scroll to load frame two let's paste it underneath our fetch database function now since fetch database now has a bunch of return values we will simply copy those variable names actually those arguments and we will assign them to fetch database okay because you remember fetch database returns the table name and the table records and then we are just pre-processing them inside the next function cool now let's save everything and let's give it a run and each of our characters is in a separate item of a list which is not what we're looking for we would like to join them so let's go back to our code and we'll do just that actually let's close the skinter app cool so we will simply use the join method so we'll specify an empty string followed by dot join and we will wrap our entire list comprehension in a set of round brackets beautiful once we do so we can then save everything and let's check if it worked let's press shuffle okay much much better and now that our title is perfect we can take care of the ingredients so let's iterate over the list of records with for i in table records and if you guys remember the very first field was the id which we don't care about so we just skip it right after we have the name which is given to us by i at index one right after we have the quantity or qty which is given by i at index two and lastly we have the unit which is given by i at index three awesome now let's go ahead and assemble these into something along the lines of two cups of sugar now two is of course the quantity so we start with q t y and we will append a space character to it because we have a space next we have the cups which is obviously the unit so we will concatenate unit followed by a string of space of space and lastly we have sugar which is the name so we'll just type name and this is exactly how our ingredient strings will look like so what we'll do is we will first create an empty list right before our for loop and we will call it ingredients we will then assign it to an empty set of square brackets so within the body of the for loop we can then append our fancy string into this list so we will type ingredients dot append and we will copy this line of code from below and paste it inside those round brackets which my head blocks traditionally now in the very very end of this for loop actually outside of this for loop we will also print ingredients just to double check that everything looks good and it grammatically makes sense so now let's save everything and let's test it let's see how it looks like okay we'll press on the shuffle button okay so we have two of garlic clove we have eight ounces of lamb we have two tablespoons of butter that seems very very logical awesome and now we can finally move on with populating our second frame and first we will finish our pre-process function by deleting those print statements and we will return the title as well as the ingredients we will then copy those variables we will scroll down to load frame two and we will unpack our preprocess function into those variables right because right now we are returning some values now in order to properly switch between frames we will need to start each frame with a tkraze method now what this method does is it stacks one frame above the other so that the most relevant frame would be on top and the least relevant frame would be below it and we'll need to repeat this command across both our frames so let's just copy it let's paste it inside frame 1 and let's adjust frame 2 to frame 1. beautiful next we can finally place our widgets on the page now the first widget would be the logo so we'll just copy it from frame one and we will slightly adjust it okay so let's paste it inside frame two let's fix the indentation of our comment it's not very important but i am picky and the first change would be a different photo so we will load uh our recipe logo bottom this time and the second change would be placing this widget inside frame 2 rather than frame 1 and then lastly we'll add a bit of padding so paddy equals 20. that's all next we have our title which is a label widget so we will copy it once again from the previous frame we'll paste it below fix the indentation of course actually fix it multiple times now it looks about right so first we will display it inside frame two then we will assign the text to our title and we'll get rid of this space just so everything looks consistent and we'll switch the font from tk menu font to tk heading font because after all it's a title so it's very important it will then also increase the size to 20. and maybe we'll just add a bit of padding so let's go for paddy equals 25 whatever we'll see if it looks good if not we will change it now right after this we have our labels and to display our labels we will first need a for loop because there's a bunch of them so we will type for i in ingredients and for each of our ingredient strings we will create its own label fix the indentation of course place them inside frame two of course we will switch the text to i which is each of our ingredients one at a time now another thing we'll do is we will reduce the size of this phone to 12 and that's it i don't think i want to add any padding at this point of time we'll just leave it as is and then we are left with the last widget on the page which is the back button so once again we will copy i love frame two because it's all about copy and paste okay all the hard work was done earlier okay so we will make sure that we are out of the for loop we don't want to repeat this button time and again we will fix the indentation okay let's double check that it's not within the for loop awesome it is not within the for loop now we would like to display this button inside frame two and we would like the text to be back so we can go back to frame 1. now we will also slightly adjust the heading font to a size of 18 because it's not very important and we need some room for our ingredients and the last thing we will need to adjust here is instead of loading frame two we will need to load frame one because the back button gets us back to the first frame okay now everything looks good let's save it and hopefully it worked so let's run our code so far so good let's press on shuffle okay wow look at that it looks amazing so does it mean we are done let's verify that let's go back and we are not done so what's going on here now since we are creating brand new widgets inside our load frame functions each time we call them we just keep adding and adding and adding new widgets to the frame until everything looks like a huge mess so before we add new widgets we need to find a way of disposing of the old ones one way we can solve this is by defining a brand new function called clear widgets and this function will take in one parameter which would be the frame we will then select all the widgets of this frame with for widget in frame dot w info as in window info underscore children as in the widget children of our frame parent now once we have selected all our widgets one at a time we will then type widget and we will call the destroy method on them so now that we've defined this function we will also need to call it so let's go ahead and copy this function definition we will then scroll all the way down to our load frame one function we will paste it at the very very top and we will call it on frame two because once we are inside frame one this is the perfect opportunity to clear frame two now we will do the exact same thing with load frame two so let's scroll below let's paste clear widgets at the very very top and we'll call it on frame one this time now let's save everything let's give it a run let's press shuffle okay two problems and one of them is only on my end so the first problem is my window doesn't adjust to the size of the elements on the page okay i need to do this manually and this is just because i'm using the geometry method instead of the eval method which i'll turn off right away now another problem is those white annoying corners so let's go back to our code and let's turn them off so it's the perfect opportunity to comment out our geometry method and to comment in the eval method and now the code on my end is 100 match to the code on your end now the way to get rid of the annoying white corners is to simply add a sticky attribute inside our grid method and to set it to north east south west that's it and that way we are asking our frame to be expanded or to stick to all four corners of our window now let's save this code and let's give it a run okay now i'm gonna have to manually move my window away and let's press on shuffle okay so far so good but the window didn't really expand so there's uh we wouldn't see those white corners anyways let's just keep shuffling until the window expands ha okay beautiful so our window expanded and we do not see those annoying white corners awesome so let's keep testing just in case yep yep everything looks good awesome now one thing we should keep in mind that inside my wireframe the list of ingredients it had a nice darker background so let's do it so we will navigate to our load frame 2 function we will find our list of ingredients and we will set their background color to a hashtag 28393a which is the exact same color as our button now in addition if we'd like this background color to expand until the full width of our screen we will also specify the fill equals both argument inside our pack method now let's save everything and let's check if it worked let's press shuffle beautiful look at this awesome background behind our ingredients so let's press back again just in case we will keep testing it awesome it looks great now if you're using linux or mac your application is complete and you can officially distribute it across all operating systems i'll actually show you exactly how to do this in the next few tutorials however if you're using windows i'm going to show you how to make this app much much prettier by using costume fonts now keep in mind that once costume fonts are involved this application will be much more difficult to distribute across all operating systems not impossible but much more difficult because you'll have to revise my logic in a certain way so for example you can first of all check which operating system the user has and based on that you can determine whether to use custom fonts or not so first of all we will need some truetype font files which you can find in the fonts folder of our starter files of course they're shanti regular and there's ubuntu bold next we will need some kind of a media library to load those files and i find that it's very simple just to use pi glit that's why we'll install it with conda install c conda forge pi glit pip install piglet if that's your choice beautiful now i already have everything installed so i obviously don't need to do this again next we will import piglet and we'll then load both our fonts to do so we will type piglet dot font dot add underscore file that's it and inside we'll just specify the path of our font with fonts slash ubuntu bold bold.ttf and we'll do the exact same thing for shanti so let's just copy this line of code let's paste it below and we'll load shanti regular now the fun part is replacing every instance of tk heading font with ubuntu and every instance of tk menu font with shanti not shanti regular shanti not ubuntu bold but ubuntu okay so just copy ubuntu and let's scroll down okay tk menu font turns to shanti tk heading font turns to ubuntu and let's do this for all our widgets okay let's save everything let's give it a run ah i ran the wrong command oh no okay so uh let's press the up arrow twice okay sorry guys beautiful look at this amazing application you guys oh my god let's press shuffle this is phenomenal let's press back let's keep testing it i love it it looks so good can you actually believe it's skinter i still can't i'm amazed now thank you guys so much for watching i really hope you enjoyed this tutorial and if you did please give it a huge thumbs up and share it with the world if you'd like to be extra awesome you can always subscribe to my channel and turn on the notification bell if you have anything to say or any questions or just if you want to say hi maria you can always leave me a comment i read all of them well at least vast majority of them and yeah i'll see you guys very soon in a brand new tutorial so for now bye-bye
Info
Channel: Python Simplified
Views: 160,297
Rating: undefined out of 5
Keywords: tkinter, tk, gui, graphic user interface, ui, user interface, graphic interface, app, application, sqlite, sqlite3, sql
Id: 5qOnzF7RsNA
Channel Id: undefined
Length: 45min 53sec (2753 seconds)
Published: Wed Jun 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.