Creating custom components in tkinter with classes and functions

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this part I want to talk about a really important part of T Kinder and that is creating custom components what that means is to use tickhinder or literally any GUI framework efficiently you need to be able to create your own components for example when we use the classes in the last bit we have created a couple of custom widgets one example was the entry widget what we created looked like this and what is really important here is that this entire thing was one frame that we customized so we gave it a label with a background and a button and once we have that we could create this multiple times so we had another label and another button besides that we also created this entire side panel as a separate widget I suppose I should look at all of this in code straight away here's the code of what we just covered before and all of this gives us this kind of app the really important thing you have to understand here is that we are creating custom widgets this entry here inherits from frame and adds more stuff to it so this Frame here this we can do multiple times we have one frame and we have another frame this one here both of these were very easily created we did all of that inside of Main in here we can simply create one entry and another entry I could duplicate this again add entry free button free and for the color I could go with green if I run this thing now we have a third entry widget with this kind of system we can create more complex layouts fairly easily and also keep them more manageable which is why it is really important that you understand how to use all of this I'm going to practice it in this video as well but definitely play around with this in your own time although more importantly for this video what I also want to cover is that there are two ways to create custom components the first one we have already seen is by using classes inside of a class you inherit a widget and you add custom parts to it this can create really complex layouts but the downside is if you end up with too many small bits you might have a ton of classes which would be a bit annoying to manage to account for that we have the second approach and that is a more functional approach all we are doing in here is we are creating a widget inside of a function and then return the widget this is a bit more limited in terms of what we can do but the upside is we can create lots of small components inside of a class basically what you want to do for any more complex component you want to use a class but inside of this more complex component you want to use the functional approach to create simpler bits all of this is going to make much more sense when we actually make the app speaking of which what we're going to make is going to look something like this in here we have a couple of custom components the most important one is each of those rows is One widget and all of those are made using classes inside of this we have three columns we have a label we have a button and then we have this kind of thing with an entry and a button for this final bit here I want to use the functional approach for the simple reason that this isn't particularly complicated we simply have a frame with two widgets inside it wouldn't really mirror it using a whole class but I also don't want to create too much of a layout inside of the class itself in the init method but well let's jump into the code and let's have a look at all of this once again I already have a couple of lines of code ready if I execute the entire thing we have a basic window with a title but not much else with that we have to figure out how to create this kind of thing what I want to start with is that these rows are always one widget and this I want to create by using a class which means I want to get started by creating a class and this I want to call segment I guess is a good name this has to inherit from ttk dot brain inside of this I want to create a Dunder init method this one itself we need a parent on top of that we need a label text and we are going to need a button text that way I can customize the entire thing quite a bit easier for reference once again inside of each segment I have a label and I have a button once I have that I can actually create the widget itself for that we first of all have to run this super init method and set the master to the parent with that we basically have a frame and essentially what I want to do inside of the global scope I want to create all of the widgets the important Point here is I only want to call the segment and tick hinder or more specifically the class itself should take care of everything else all I want to pass inside of the segment is the parent which is the window that I want to have a label text let's go with label and I want to have a button text button and that is it I don't want to do anything else inside of the global scope the entire logic of this widget should be inside of this segment that way we have one component that takes care of everything and we don't have to think about it too much what this allows us to do is duplicate this a couple of times and we have different widgets that can do different things for example in this case we would have different labels let's say button and click or hello and test it doesn't really matter what you place in here the important thing that you have to understand is that we are creating a custom component that contains a huge amount of logic to get started in all of this inside of the segment class I want to create a grid layout for that I want to get self and row configure although for this one I want to have row 0 with a weight of one and that's basically it although with that I can duplicate the entire thing change the row to a column instead of a zero I want to have 0 1 and 2. I want to have three columns that all have the same weight on top of that I also want to set uniform to a or it doesn't really matter what it is but with this all of the columns are going to have the same size almost specifically the same width inside of this I can now create a ttk label and I can create a ttk button both are going to need fairly similar arguments the first one is the parent that is going to be self besides that we also need text this text we already have because we have the label text and we have the button text for the label I want to have the label text or the button I want to have the button text after I have that I want to use the grid method to place both of the widgets the label is going to be in row 0 and column 0 as well all of this I can copy as well because the button is also going to be in row 0 but column is going to be one if I run the entire thing we can see that we well cannot see anything the reason for that is that this segment is not being placed on the window which means we have created a component but we are not placing it for that we need well a placement method and this once again we can do inside of the component itself all I have to do inside of the init method is self and then use one of the layout methods I'm going to go with pack with that we can see the different layouts although right now all of this looks a tiny bit weird so not ideal yet first of all I want to set this to expand being true and fill should be both now if I run this this is starting to look a little bit better although I need a few more widgets to make all of this look halfway decent that we can do very easily because to create more widgets all I have to do is duplicate this segment and we get more widgets although I'm going to change the text here so we can see a bit better what's going on I will just add random words in here it really doesn't matter what you add here it's just for illustration anyway let's say exit and now we have five different segments this still isn't terribly visible because there's so much white space in here the reason for that is that both of the label and the button only take up the minimum amount of space that they need to display the text that we can change by using this sticky argument and I want to set sticky to north south east and west now if I run this all of this starts to come together much better what you can also do is inside of this pack method set pad X to 10 pixels and Pat y should also be 10 pixels if everyone is now we have a tiny bit of white space between the widgets and that is basically it I don't want to repeat myself too much here but what we have done is we have created a custom component called segment and inside of the segment we have a ton of logic that way inside of the global scope this bit here we can simply create one component and this component creates something much more complex in the app just imagine if we didn't have this kind of setup we would have to create this code up here five different times and if we wanted to update any individual bit let's say this hello here we would have to go through a lot of code just to find this one part which would be really annoying to work with but in our setup here all of this is very easily manageable which is why you really have to understand this now this is one way to create this kind of layout system there is another way though what we have done for now is we have used a class-based approach to organize our widgets but this we don't have to do we could also use a functional approach let's have a look at this one by translating our class-based approach to a functional one back in the app I want to all the way at the top create a function I'm going to call this one create segment this one is going to need three different arguments we need the parent we need a label text and we need a button text for the Keen item on you those are the same parameters we have used here we don't need self because we're not using a class inside of this function we are basically trying to recreate all of this and then return the result basically what that means is I want to create a frame which is just going to be ttk and frame at the end of the function I want to return that frame which essentially means that we are taking this Frame here except now we are keeping it by itself although first of all we have to set a master for the frame which is going to be the parent we are passing into the function this parent here next up we have to create the layout this grid layout here I suppose I could just copy the entire thing paste it in here and fix the white space we don't have self anymore instead we want to set the frame with rows and columns after that I want to create some widgets I suppose I should be a bit better here with the comments what we have done in the class based approach was also creating widgets that way all of this is a bit easier to read in my case I want to copy all of this and paste it inside of the functional approach now we have a ttk label and a ttk button although once again we don't have self anymore instead I want to parent them to the frame the frame we created up here with that we have the same thing we created inside of the segment here which means now that we are returning it we can simply use it which means all of this here I want to comment out and if I run this we can't see any widget anymore and let me minimize the class now you can see roughly the entire app instead of using a segment I want to create segment and for the arguments I have to get the parent the label text and the button text these three arguments if I run this now we still can't see anything because what we have done inside of this function is create a widget but we are not placing it this we could have done inside of the segment very easily because in here we could simply run self.pack this unfortunately we cannot do inside of the frame because we are returning the frame we couldn't place it right away although what we can do since this function here is returning a widget we can on it run a layout method like pack for example and this pack could be expand true and fill both like so and another runders we can see we have one widget although since we only have one all of this looks a bit weird but what I can do now is simply copy all of this let me add some white space uncomment it and instead of a segment I want to use my function create segment since we're using the same arguments all of this should still work also don't forget we have to add the pack method to all of them like so and now if I run this we have the same result although I did forget one thing and that is the padding for x and for y let me copy it from the segment class and paste it inside all of them so we get exactly the same result now if I run this we have exactly the same result and we have done all of this by using either a function or a class both would be fine in this instance because we are creating something fairly simple but once again I want to emphasize if you want to create more complex layouts having either something like this or something like this let me uncomment it is much easier to understand and to maintain than having a ton of widgets that you all create manually for future videos I am going to rely a lot more on custom components so this is an important thing to understand which means Let's do an exercise and I hope you can still keep up all we have to do is an exercise and then we are done what I want you guys to do is create a smaller widget inside of the segment class using a function or a method specifically inside of this segment class I want you guys to use a function to create another widget like we have done up here instead now don't use a function use a method inside of this class what you should be doing is create a container that has an entry field and a button stacked on top of each other the button should be set by the parameters and all of this should be inside of the third column of this segment as a reminder we are creating three columns and right now we are only using column 0 and column one at the end of this out of this should look something like this we have an entry field and we have a button for all of my buttons I use the text exercise but this should be more customizable pause the video now and try to figure this one out yourself alright let's get started I want to work inside of the segment again although first of all what I should do is comment out all of these functions because I only want to work with the segment class inside of this one I want to create a method let me call it create exercise box for this one we need two arguments we need self like for any method and then I want to have some text this is going to be the button text now inside of this method we have to create a frame like we have done up here with create segment we always start by creating a frame in this Frame we are returning at the end although this Frame while being ttk and frame has a parent of self or a master to be a bit more specific at the end of this method I want to return this Frame although before we are doing that I want to create a ttk entry this one is going to have the parent of frame and besides that I want to have a ttk button this one has frame as the parent but also text is going to be the text that we are getting from the parameters this text up here we are passing in here once we have that we have to place both of these widgets inside of the frame and this I want to do with the pack method since both of the widgets are supposed to be on top of each other I don't need a side but I do want to set expand to true and fail to both and that is all I need inside of this method with that I can minimize it now inside of the widgets I can call self.create exercise box and add the text in here for now let's go with exercise if I run the entire thing now we still can't see anything because once again I forgot that we have only created a widget we haven't placed it yet for that we need the grid layout method so grid I want to have a row 0 and column should be 2. on top of that I want to set sticky to north south east and west and that should cover it all meaning if I run this now here we have a pretty good looking result we have an entry field and we have an exercise button I hope you can see the value of this because now inside of this class when we are creating the widgets we have all of this in a fairly logical layout we are creating a label a button and then an exercise box now this exercise box could be a separate class that would be perfectly fine but since it is so simple it's only four lines of code you don't really have to do that it's kind of an Overkill which means in this case simply using a method to create something slightly more complex is perfectly fine and much easier to maintain although there's one more thing I do want to do and that is that right now we always use exercise for the text for the button but this I want to have a bit more customizable so when I'm creating this segment I want to have another parameter and that is going to be the exercise text this exercise text I'm going to pass into this function like so and now when I'm creating all of these segments I have to add one more argument let's go with test just to see if this is working and there we go now we have test for all of these buttons I could change this the first one could be test the next one could be something else then we have one two three we could also have an empty button or we could have end it doesn't really matter but now we have different kinds of text in here and everything is still very easily maintainable all of the customization happens in here and this is very easy to see and very easy to understand and if you want to make changes you have all of this contained inside of one class that is maintainable and very easy to work with
Info
Channel: Atlas
Views: 19,481
Rating: undefined out of 5
Keywords:
Id: 0y1kYxOp8hE
Channel Id: undefined
Length: 20min 35sec (1235 seconds)
Published: Tue Dec 20 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.