 All right, let's take another look at the data class and this time we're going to look at it in QML I have a skeleton of the basic interface we had which is the name species animal and fed Special note on QML. There really is no concept of a date time picker at the time of this recording Super super special about that. All right, so let's take a look our QML is very very basic First things first. We're going to import the class we used from the previous project So let's go into 15 for grab this and We're on 15 6 Paste it in there and let's right-click and let's add existing files add the animal implantation and header Give it a minute to think about. All right You'll notice right off the bat. It doesn't know what Q concurrent is So you guessed it we have to go in here and same thing. We have to say concurrent and Then it should know in C++ land once it's done parsing that what Q concurrent is and we can now use our data class Because we're in QML land. We're going to be working primarily with these Q properties, which is why put these in the original file remember quick recap if you're watching these in order, this is probably boring, but Q property is needed because QML has no concept of these public Functions so it won't see the getters and setters. It only knows signals and slots So it's only going to see these guys here. Now the properties act as kind of a bridge between that So now we can say we want a property a string that has a getter and a setter and is going to have a signal It's going to let us know when it's changed This is what's extremely cool about QML is that you can have this property system in place So you can get automatic notification of when a value changes and it updates your GUI for you It's actually really cool And special note If we do a to file from file, this is all concurrent meaning it's asynchronous It's going to run on a separate thread and we don't have to take care of any of the threading complexities We covered all of this in I think it was video 15 for when we actually built this class but just in case From file to file both of them get a Q future that calls Q future concurrent run on this object And it's going to call concurrent IO with a path and a read only or a write only This Q future is going to be set inside of the watcher. So we're going to say hey go do this I'm going to worry about it in the future and then watcher. Tell me when it's complete That's really what we're worried about here. All right, we're not done yet So we've got a little bit more C++. We're gonna have to do in our main this is What I would consider probably the only real downfall of QML in order to use this We need to include the header file because it's a C++ class and then we need to register this with the QML engine Otherwise our QML code will have no clue that that class even exists So let's jump in here And let's say QML register type And we're going to register an animal and then we've got some special nonsense We need to do and I call this special nonsense because I absolutely hate the way this is set up But I understand why they did it. So we need some sort of ID. So we're gonna say come company Animal and that is basically our namespace and then we need a version major and minor followed by the actual name that we're going to Use inside of QML Now from here what we can do is we have a namespace So if you made an animal and I made an animal as long as they're different company names Or if you make a completely different namespace all together those two will be treated differently Special note in Cute six which is coming out soon I've heard not confirmed, but I've heard when we do QML the versioning doesn't matter as much And what do I mean by that? Let me go ahead and grab this We're gonna jump into QML. Let's go ahead and import that some say imports And we're going to import that animal and we want the major and minor version Now you notice in QML. We have to have the versions in there. I've heard in cute sick It's going away. It's gonna be something like that and it will try to load the newest version Alright, so now that we've imported our animal class. We have to actually use this So the very first thing I'm going to do is go all the way down to the bottom of this file here And I'm going to you guessed it say Animal and if you're wondering how I'm getting this name we define this in our Main here where we said we want this to be the name we're going to use for the QML object type so there's our animal and I want to say ID Animal and now we want to hook into The signals so I'm going to say on finished and Then I'll have something and then we're going to do the same thing for On air Probably help if I was outside of that There we go. And now I want to know when the component Uncomplete is fired it off That's when I want to call my internal function here called Update GUI which is going to have the animal name animal species animal age and all that fun stuff already in it So this is how we're really going to update Right off the bat here. So I'm going to say update GUI So as soon as our component is loaded, we're going to load with all the default values there And you guessed it pretty much the same thing for finished Now if we have some sort of error, I want to do it kind of the QML way And I'm say console log you could pop up something to the user But for this I'm just gonna say console log whatever the message was and There is our animal in all of its glory Now you notice I already have some of this stuff sprinkled in I just kind of left the non important stuff in there But we're going to go all the way to the top And we're going to see what we need to put in here. So first things first. We got our import. We've already created our object Now we're going to go down to our button saved. All right right here This is where we need to you guessed it pop in Our setters here. So what we're doing is we're working with the cute property system here And QML is a little finicky when it comes to date. So I have this Verdi Necal new date and then we've got it the text fed dot text So really what we're doing here is we're going to say animal name. Now, where are we getting these? If you look at this it looks like we're calling a C++ getter, but under the hood we're saying animal dot Name species age and if we flip into this header, you're right. It's the property name species age This is what I mean by QML doesn't understand public. So if I try calling, let's say set species Let's try that. I'm gonna just do it right here. I'm gonna say animal And let's say set and nothing happens. IntelliSense is not even going to help us out Because it just doesn't understand what it is. So we have to use the cute property system All right now that we've got our save button in there We have our clear button which is going to have the animal clear in it and then our load Which is the other important little bit here and I'm going to just you guessed it clear out our GUI and then we're going to call our Open dialogue Now the important part really happens in these two dialogues I've got save and open and these are non-visual and they fire off when we click those buttons So I've got a path here and I'm just saying go ahead and get the file we want to save And I'm going to say Animal and I want to file now you may be going now wait a minute. I thought you just said It can't find those setters because it can't read the public functions. Well, if we look at animal It is a slot to file from file So anything you want QML to be able to call directly needs to be a public slot All right, so now that we've got that nonsense out of the way We can just simply plug it in it becomes ridiculously simple So I'm going to say save is going to go animal to file and Then open you guessed it is going to be animal from file And we're going to put that Right here bang Very simple very easy to understand the rest of this is just boilerplate clod Boilerplate code that just loads all the animal stuff in there. Let's save and run all right, so Immediately we know it worked because it's loaded all this stuff up and let's go ahead and say Rango Rango, what is he? I don't know. He's just a big Fat dog is what he is my wife's dog. He's just a big fat dog And we're gonna say he's 10 years old. We're gonna save this and let's call this Rango one dot txt and we can clear this out do whatever we can even close the application rerun it and Let's go ahead and click load and there's Rango one. We're gonna click open. Let me pull this up so you can see it and Then Rango our big fat dog with his age and everything Deserialized the way we would expect it to so I know we kind of whip through a lot of the QML stuff again This is not a course on QML. This is a course on design patterns And what we're really hyper focused on is how to make a data class and work with that class inside of C++ widgets and QML now the specifics for QML to take away for this video is When you're in QML, you have to work with the Q property system if you want to interact with getters and setters That being said you can also work with slots now. You may be inclined to say hey I will only work with slots because I hate the Q property system Don't do that. You're gonna run into all sorts of issues here. So Really what's going on? Let's look at this here When we Call the open buttons clicked it's gonna call the open dialogue and this is gonna say animal from file Now what's happening here is we're saying animal on finished update The graphic user interface and then we're just calling those getters back You can do and I haven't done it in this example But what you can do is full out property binding. So this updates automatically So for example Let's copy. Let's comment that out and let's Go ahead and load this. I'm gonna say rango one Notice how it didn't load. It's because we're not doing cute QML property bindings That's a totally separate subject But if you wanted to do that you have everything at your disposal because we have the Q property system in there So Quick recap we made a data class We've used that class across the console across the widgets and across QML and we've talked about a lot of the pitfalls The major thing to really understand here is that IO is dangerously slow for graphic interfaces QML it's extremely vulnerable because QML we tend to run these things on embedded devices Which are much slower than your standard desktop application So if I was running this on say a raspberry pi with very little ram and there's a bunch of other programs running and The IO is already completely taxed and then I go to load this file We could lock up this interface unless we're doing it on another thread