 Hey everybody, this is Brian and welcome to the 50th Qt Tutorial with C++ and GUI programming. Today we're going to cover delegates. In case you're wondering what a delegate is, there's a lot of examples out there about the spin box delegate, and it's actually built into Qt Creator. If you go choose example, item views, and then spin box delegate, you'll get the complete source code for something very, very similar to what we're about to do. But basically what a delegate is, is this little guy right here. It allows you to view and edit an item within a model. And you can decide exactly how you want to do that. What we got here is basically a model with a table view. And in the table view, when it goes into edit mode, there is a Q spin box that appears. And you can change that to pretty much whatever you want. So let's go ahead and actually build something real quick here. GUI application, and let's call it myDelegate. Put it in the usual location. Let's just give it a dialog. Next, next, finish, finish. Alright, and let's grab a table view. Throw that out there real quick. Save your work. Alright. Now the first thing we want to do here is actually go into dialog.h. And we're going to create our models. Let's just make a few includes here. And let's add in Q standard. Sorry about that. The Q standard item model. What this allows to do is just make our own model with our own data. Pretty much anything we want to throw in there. Now we'll say model. We want a new Q standard item model. And the constructor for this is a little bit different. What we want is the number of rows, number of columns, and the parent. Then we can go ahead and attach this. We'll say save your work. Now there's no data in our model. So if we run this, it's not going to display anything. So what we need to do is actually generate the data for this model. We're going to save for each row. Row is less than four. And we're going to increment the row. And then for each column. I forgot the type there. Call is less than two. We're just going to increment it. Now how you input data into your model is very simple. The first thing you need to do is get the index to it. So let's say Q model. Oops. Q model index. We'll just call this index. Let's actually just put that out here. Equal. Let's say model. And we want the index of a specific row and column. So we want row, call. And it's going to want a parent. And for that you can just give it a new Q model index. Put your semicolon at the end there. And that's how you grab the index. Now what we need to do is actually set the data. And it's going to of course want the index of the item we're going to update. And then the data. And for this example, let's just put zero in there. Save your work and run it. What this does is it just prepopulates our entire model with data. All of it's going to be zero at this point. So after this builds and runs, you see there's our model. Now one thing you should note if you're just walking into this is Qt has this functionality already built in. You see when you enter edit mode, there's the spin box. But we're going to show you how to implement a custom spin box all of your own. Okay. Now what we need to do is create a new class. And we're going to call it delegate. And it's base class. Whoops. It's base class. It's going to be a Q item delegate. And it's going to inherit from Q object. And then go into dialogue H. And you'll see we've got just a very simple class here. And we're going to have to add a few includes. We need Q model index. We need Q object. We need Q size. And of course we're going to need the spin box. So now we've got our class, which inherits a Q item delegate. One thing you should probably do is go out to the help file and look up Q item to see exactly what's going on here. Well, the Q item delegate is a class that allows you to create your own delegates. And you see the virtual functions here are create editor, set editor data, set model data, update geometry, size hand, et cetera, et cetera. We have to actually implement these. Notice how they're virtual. All right. So let's go out here. Now one thing you can do is just copy and paste. It's almost a little bit easier just to actually let the editor do work for you. And you see how it just puts everything out there for you. So it really minimizes your typing. I'm not a big fan of typing. So I say, you know, if you can get away with not typing, let's do it. And we're just going to create our function prototypes here. So I forgot to semicolon there. And let's do void update editor geometry. Now if you're wondering what these do, they're actually very, very simple. When this is first run, the delegate doesn't even exist. So the view will call create editor. And that will create the editor or the delegate in the background. Then it will call set editor data, which is the current data in that cell. You then modify it. And when you're done modifying it, it calls set model data to return the data back into the model. Update editor geometry is how the queue spin box actually knows how big it needs to be and where it needs to be on the screen. Without that, it just floats into the upper left corner. And we'll kind of see that later on. And you can just copy these. Go right into your implementation file. Paste them. And look through the magic of copy and paste. We can just implement these really, really quickly here. And at this point, I'm actually going to pause the video. I don't like chewing up a whole lot of video time. Just copy and pasting. So I'll be right back. All right. I'm back. And I've got the implementation file pretty much fleshed out. Now, one thing we should do is go back into our dialogue. And let's actually include this real quick. Bro, forget. And then we're going to create a delegate here. And we'll just call this delegate. Actually, that's called my delegate. Now we'll grab this. We'll go back into our dialogues implementation. And let's actually create one of those in memory. So we'll say my delegate equal new delegate. And give it this as the parent. That way, it's in memory. It's ready to go. And let's actually set the delegate. Ui, table view, set item delegate, my delegate. That's how you actually set the delegate. And you should know if you don't set this, it'll just use the default delegate. All right. Jump back into our delegate implementation file here. And this is where the real heart of this program runs right in here. So remember the create editor. This is called when the view needs to create the editor. So we'll say queue spin box. And we're going to create another, a new one of these. So we'll call it editor. And you just want to give it to parent. And very simply, you just set the minimum and maximum and then return it. So we'll just say set minimum. We want zero as the minimum. And let's say the maximum 100. And then we just simply return the editor. Because at this point, the only thing the view cares about is it wants to grab this editor. So it knows it has it. And then it can start using it. Once it has it and it wants to start using it, it calls editor, or I'm sorry, calls delegate set editor data. This is how the data gets from the model view architecture into the delegate itself. So first thing we need to do is get the index. We'll say, I'm sorry, get the value. We get the model from the index. And then we want to get the data. And if you're wondering what cute edit rule means, each item in a view has a different role. And what we want is the edit role. And we just simply want to say to int. So very simply, all we're doing is we're saying, we want the value out of the index. And to do that, we have to get the model and then the data out of the edit role. Sounds pretty complex, but it's actually not too bad once you really sit down and think about it. Then we have to put that value into the spin box. So we'll say, cue spin box. We'll just call this spin box. And we want to do a static cast. And let's just, we're casting the editor here. That's how we know what type it is. And then we just say spin box. Whoops, hope if I could spell it. And we're just going to set the value there. And remember, you're getting all these from the parameters. See, we're getting the value here. And then we're setting the value there. Now the set model data, that is when you are done editing it. And you want to return that data back. And at this point, let's actually just run this program without even implementing that, just to see what happens here. Tick tock, tick tock. I wish I had some really cool theme music. This is building, we could just play it. All right, now here is your model view. And when you enter edit mode, you notice how our spin box is up in the corner. It's because we haven't called the geometry yet. And if we just enter 55, notice how it's not going back into the model. But when you start, it's automatically zero. It's because we haven't implemented that yet. The set editor data, remember that's how the data is going from the model into the delegate. Now we have to take the data from the delegate back into the model. So we'll say queues spin box. And you guessed it, just kind of work some copy and paste magic here, just save us some time. And we will say spin box. And we want to interpret text. That will force it to interpret the value that's been put into it. And we'll say int value equal. And we want the spin box value. And then we want to model, we want to set data. Because remember we're going to put the data back in. We put the index, the value, and then of course the role. That way we know this is coming from the edit role. That's how you put the data back in there. And we of course want this to be placed correctly. So let's just do an editor, set geometry. And we want the option parameter rect. So really all you're doing is you're just saying the rectangle of the cell that this came from. Save and run. And let's do this one right here. Notice how it is set geometry, put it in the correct place. And when we type 55 in exit edit mode, it puts it back into the model. And if we go back in, there it is. So we can say 44, let's just 88. You can see how this works. And you can use the spinners up and down. And notice how when it hits the minimum it stops. And if we put it at 99 and then try going up, it won't go past 100. Pretty neat. So that is how delegates work. And I realize this is a very simplistic example even though it might have sounded a bit confusing. One thing you should do if you just kind of shook your head at this whole example going, what in the world is he talking about? Is go into the spin box delegate example. And you have the complete source code there along with the official cute documentation and instructions. So this is Brian. I hope you found this tutorial educational and entertaining. And thank you for watching.