Using tkinter with classes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's talk about using classes in tkinter and what we are going to make is going to look something like this this is the same layout we have seen on the last part except now we are using classes to organize all of this which is making the entire app significantly more manageable let's talk about it and then we can Implement all of this the most important thing that you have to understand is that we are basically always taking some kind of widget usually a frame but it doesn't have to be and then we're adding widgets to this Frame and then in the end we are placing this Frame somewhere on the window that way we can organize lots of widgets very very easily if you understand basic tkinter this shouldn't be too difficult to implement although to make all of this work let me show you my setup here I have two python files open on the left side we have classes dot Pi this is what I'm going to work in on the right side we have the previous code from the last video this is the same layout or the same app except that we are not using any classes so what we are going to do in this video is convert all of this into class based approach that way I can switch between the two and illustrate what's going on now first of all we have to import the basics this I can just copy straight away I want to import tkin to SDK and I also want to have ttk now that we have that I want to create a class I'm going to call this app but you can name this whatever you want this app is going to become the window essentially this bit here is what we have to turn into a class the really important thing here that might be a little bit complicated is that this app is going to inherit from tk.tk which means that the app here is going to be the main window let me implement it straight away this app is supposed to inherit from TK dot TK in the function based approach this one here we have stored this object inside of the window variable in the class-based approach we are storing the object itself once we have that I want to call a Dunder init method for now this one just needs self and nothing else in here there's one really important thing that we have to do before anything else and that is to call Super and thunder init this ensures that this TK functionality works properly although besides that we don't have to add any arguments so this one can stay as it is with these lines of code we basically have replicated this one line of code here so far we have just become less efficient but what we can do now is get self and for example set the title the title could be something like class based app this would be the equivalent of this line here let me expand it a tiny bit like so in the function-based approach we got the object which we called window and then we called the title method on it this we can simplify here a tiny bit because the object itself is well self and we can still call the method on it because we inherited the entire object and this is one method of it to illustrate how all of this is going to work let me go all the way down in the functional approach and run window.main Loop in the class-based approach this would be self dot main Loop without any arguments with that approach we can simply create an instance of this object and run it and if I execute the entire code now we can see we have a window that also has the same title class based approach there you can see it better although right now our app is one class that is a lot easier to manage not for now but it is going to be much easier so besides that I want to also duplicate these two bits here which means inside of window I want to get self and I want to set the geometry of this class or this app to duplicate this I want to have the same Dimension 600 by 600. I can run this again and there we go we have a larger window the same I can do if I duplicate this line I can set the minimum size here for this one we just want two numbers with 600 and 600. that way if I run this again I cannot make the app smaller than 600 by 600. and with that we have copied all of this here to set up our window although I do want to make some minor changes and that is I want to set the title and the geometry from the arguments that we pass into the class when we create the instance of it which means inside of app I want to pass in a title let me call it a class based app and then I want to add a tuple with the width and the height which in my case is 600 by 600. which means I have to update all of this a tiny bit to account for these arguments here which I think could be a fairly good exercise for you try to update the code to account for these arguments most of you now and see if you can figure this one out first of all we have to add two more parameters to a niche I want to have a title and I want to have let's call it size the title is very easy to change because this one is just a string which means inside of title I can pass in the title the geometry is going to be a tiny bit more difficult although not very much we basically have to figure out how to turn this Tuple into a string in my case I am using an F string which means I want to add an F in here and the first argument is going to be size and zero the second one is then going to be size and one and now we should be good to go I guess one more thing that you could be doing is right now minimum size is static we can also update this one although we would use the same numbers we have used with geometry so size 0 and size 1. which means if I run this now we cannot see any difference although what I can do is change these numbers let's say to 200 and 400 and now we get a different kind of window although I don't actually want to do that and I think with that you can already see some advantages with just one line of code we can call the entire window and pass arguments into it so when we actually use the app this one is much easier to understand than these four lines here and this is only going to become more advanced for the next bit I want to work on the menu let me show this again here's the app what I want to work on is the left side this bit here in the original code I move this to the side we have a menu the menu is all of this bit here a couple of widgets all of those are inside of a menu frame this menu frame here or rather we are creating it here we are placing it here and then we're adding widgets here on top of that further down there we are adding the layout of the widgets further down here which all things combined is really annoying to manage we basically have a huge amount of code that is really really disorganized this I can change very easily by creating another class that I want to call menu this menu is going to inherit from ttk and frame basically what we are going to start with is we are going to recreate this Frame here except now we are not storing ttk frame inside of a variable instead we are creating a whole new object inside of this like with the app we have to create a Dunder init method this one is going to need itself and on top of that we are also going to need a parent or a master because inside of the init method I want to call the super Dunder init method and this one is going to need one argument and that is the master or the parent the way you have to understand this is that this init method is basically the same as calling the object by itself and for that we always have to pass in the master which in this case is going to be the window with that we have basically created another frame this we can now use inside of the app the way this is going to work let me add a couple of comments here I want to create widgets and besides that I have the main setup all the way at the bottom I am running the app the widgets right now we only have self.menu which is going to be the menu although don't forget when we are calling this menu here we have to pass in the parent and this could be an interesting exercise for you try to figure out what the parent is the parent in this instance is self because the app is tk.tk what we called window in the functional approach and in the functional approach we sort all of this inside of the window variable and passed this inside of the frame in the class-based approach let me move this a bit to the side app itself is the window so this app we are passing into the menu that way this menu is going to have this app as the master although if I run all of this we can't really see very much there are two reasons for it number one this menu right now is just a frame and frames are invisible although even if they were visible we couldn't see them because we're not placing this Frame anywhere on the app right now there's a parent or a master but we don't actually position the frame inside of the parent which means there are two things we have to work on number one I want to create a label that actually illustrates where the menu is for that I simply want to create a ttk and label like so the parent here once again has to be self I don't actually want to have text in there instead what I want is a background this one can be read right now right after creating this label I want to use the pack method and in here I want to set expand to true and fill to both that way this label is going to fill the entire frame with a red color and let me move this a bit further to the right so we can see the entire thing right with that we should be having a menu that's at least visible although if I run this again we still can't see anything because we have to place the frame itself and this can happen inside of this class as well because all we have to do is get self and now we can run for example pack or we could run grid we could run whatever we want to keep it simple for now I want to run the pack method if I run this now we can see all the way in the top we have a tiny red bar this we can set to expand being true and we can set fill to both and now if I run this this Frame is covering the entire window although in the original if I expand this a tiny bit more when we are placing the menu frame this happens here we are using the place method with all of these arguments meaning I can just copy them move this a bit further to the site again and now instead of Peg call the place method this one has X being 0 and Y being zero so menu is always on the left side it covers 30 percent of the width of the window and it covers the entire height I can run this again and there we go now we have the same position for the menu why this approach is really useful is I can now minimize the menu and inside of the app this is what I'm actually working with the entire menu is simply one entry I don't have to worry about all of these different Snippets that are in different places the entire menu is in one spot which makes it much easier to work with although right now the menu doesn't have any content so we have to work a bit more on this and let me move this a bit further to the right there we go inside of the menu I want to create all of these menu widgets these ones here for that I'm going to create a separate method I'm going to call this one Define create widgets this one itself and nothing else and in here I want to create all of these widgets so let me copy them we have menu button one two and three we have two sliders we have a toggle frame this one is a frame in itself and this one has two children menu toggle one and two and finally we have a frame all of these I want to copy and paste them in here and also fix the indentations there's one more change that we do have to make and that is that all of these buttons and Sliders don't have a menu frame as the parent instead I want to change all of the menu frame to self because all of these buttons should have this many frame as the parent with the exception of menu toggle 1 and menu toggle 2 because those two are supposed to be a child of the toggle frame meaning those we don't actually have to change besides that the entry I forgot to change this isn't many framed this should be self with that all I have to do is call this method self dot create widgets and now I can run this and we can't see anything again this happens because we're only creating widgets we're not placing them on this Frame for that I want to create another method I guess we can call this one create layout no custom parameters again and what I want to do now is replicate basically this here including this one as well as you can see in here we are using the grid method to place all of these elements which means first of all what we have to do a bit further up we have to create the grid for the menu this I have done here with these two lines of code so let me start by copying those two and once again I have to fix the indentation I move this thing a bit further to the side so we can see what's going on I want to first of all create the grid for this I can minimize the create widgets method I want to get this Frame here and I want to set columns and rows on this which means instead of the menu frame I want to get self although the rest can stay identical which means next up I can place the widgets for this once again I can copy all the stuff I have done here all of this and I can place it in here once again we have to fix some indentations like so and now we can work with this and now we have a tiny problem all of these widgets are only available inside of create widgets they are in the local scope of this method inside of here which means I couldn't access them inside of this create layout method I guess there are two ways you could approach this problem number one you could change all of these variables to attributes so for example he would turn this variable into an attribute using self and then down here you would use self.entry.place that would be one approach although in my case I don't want to go with that one so let me undo everything instead I'm going to be a tiny bit lazy here copy all of this and then place it inside of create widgets that way we are doing all of this inside of one method and we are staying within the same scope not the cleanest approach and if you had a more complex app this would probably be something you want to work on more but for this simple app this is totally fine at the very least let me add some comments here I want to create the widgets then I want to create a grid and then I want to place the widgets and with that I want to get rid of this TDK label here because we don't need it anymore now I can run the entire thing and there we go we have the entire menu still works just as before except now all of this is inside of one class and this finishes the menu which means I can minimize this and now we can see menu is simply one entry that is much easier to work with and if we wanted to work with it we could simply open this and then change all of this and do whatever change we want to make which makes maintaining all of this much easier so in comparison here's the original we had just code for the menu here here here here here here and this was very difficult to separate from the main widget for example so with that we are making some good progress next up I want to create main if I run this again main is this main area here this one is actually really simple because what we want to do again is we have main.frame here just another frame this one we are putting on the window using the place method again so this we can start on right away I want to create another class and this one I called Main once again this has to inherit from ttk dot frame and let me move this a tiny bit further to the side in here like for the menu we are going to need a thunder init method that gets self and it gets apparent spelled correctly as well like so and don't forget super underscore underscore init and pass in the parent in here this is the same thing we have done for the menu so if I open the init method of the menu we had all of this next up to actually see the main menu I want to run the place method again although I can copy this from the original video we are calling this place method here which means inside of the init method of main I want to call self and place and then place the widget in this position to make sure that we can't see this I want to once again create TDK label with self as the parent with background being red and with the pack method setting expand to true and fill to both with that I can simply create this main method inside of the app right below the menu itself let's call it main is going to be Main with self as the parent and if I run this now we can see the main frame let me minimize the menu and get rid of TDK label here we definitely know this is going to work which means with that let me show the app again we can start working on the actual entries these things here this one once again is going to be one frame inside of the frame we have one label with a background and then we have a button below for that I want to add a tiny bit more code inside of main I first of all want to create a frame so I can just call it frame and this is going to be ttk and frame the parent here is going to be self inside of this Frame I want to have a label and a button so let me create a label variable then I want to use ttk and label with the frame being the parent text is going to be let's say test 1 and the background color is going to be red after that I want to create a button and this is going to be ttk and button with the frame as the parent text is going to be I call this one test one as well although let's call it button that probably makes a bit more sense these two buttons we now have to get inside of the frame and this Frame we have to place inside of the Mainframe let's start with putting these two widgets inside of the frame for that I'm going to use the pack method so label dot pack expand should be true and fill should be both this I can now duplicate because the button is going to work in the same way with the only difference that the button has padding y being 10 pixels finally I want to get the frame and pack this one as well although for this one I want to set the site to left actually I can copy all of this from the original in here we are placing all of this if I find it really quick we are placing the main layout here we have entry frame 1 and entry frame 2. all of this I want to copy like so so let me move all of this to the site again and I want to use this pack method with all of these arguments and with that this should be working let's try now and there we go we can see the entry inside of the Mainframe we are making a lot of progress now this is starting to become a tiny bit messy because this Frame here could be its very own class and this incidentally is going to become your exercise I want you guys to get this Frame here and turn it into a separate class along with all of its children so it should be a frame class with a label and a button on top of that I want you guys to set the color the label and the button via the arguments which means you should be able to use the init method of this new class to set the text of the label the text of the button and the background of the label and pause the video now and try to figure this one out yourself let's get started first of all I want to create a new class and this one I called entry as always we have to inherit from ttk and frame inside of that we need the dunder init method in here we need self as always then we need a parent then we need three more arguments we need the label text we need the button text and we need to label background these three arguments we need to cover the second part of the exercise with that inside of the init method don't forget to call this super init method and then here you want to add the parent this entry frame here is going to be this Frame which means inside of it we can do all of this as a matter of fact let me cut out all of this and delete the frame and instead I want to paste all of these things in here now we have a label a button we are placing the label and the button and then we are packing the frame although for this to work we have to make some changes first of all label and button have not the frame as the parent instead self is the parent now or the layout this can stay exactly as it was before although for the frame itself we don't want to pack the frame we want to pack self because remember self is a frame that we can pack on the parent with that we can already create a entry frame in here the one argument we have to pass in here for now is the self although all the other arguments we are not using right now so let me simply pass in one two and three it doesn't really matter right now I can run this now and there we go we have the very same result and this is actually super useful because now I can duplicate this entry widget run this again and now we have two entry fields or frames I can do this multiple times and there we go we have lots of different fields in my case though I only want to have two but I hope you understand the principle here although next up we have to actually cover these three parameters and they are very easy to work with because all of them are going to be a string the label text is going to be the text for the label this one here which means in there I want to pass in the label text the same thing for the button I don't want to have a string button instead I want to have the button text finally let me add the comma here for the background we don't want to have hard-coded red instead we want to have the label background with that I now have to pass in proper arguments in here let's say for entry 1 I want to have entry 1 then for the button I want to have button one spelled correctly and for the background I want to go with green let me duplicate all of these and paste them into the second entry and let's call this entry two button to and for the color let's go with blue let's try this again and there we go now we have widgets that work perfectly fine and now I hope you can see the value of this approach because this makes it really easy to create lots of widgets that are self-contained for example for the entry we are only having one entry here but this entry contains a huge amount of stuff if I compare this to the original functional approach we created the frame here we created some widgets here and then we could set the layout here and this was kind of messy because in there we had the second frame and all of this was really hard to follow whereas in this approach we simply have one frame that contains it all and we are placing it wherever we need it and with that we have the entire app that is much more manageable because now we have logical parts to it that we can work with whenever we need and this is what you want to use most of the time as soon as you have any kind of complexity in your app this approach is vastly superior
Info
Channel: Atlas
Views: 44,414
Rating: undefined out of 5
Keywords:
Id: eaxPK9VIkFM
Channel Id: undefined
Length: 28min 22sec (1702 seconds)
Published: Mon Dec 19 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.