 I want to talk about automatically connecting signals and slots. And yes, Qt does do this to a certain degree. For example, if you're in widgets or QML, it may do it if you follow a certain naming convention, but it's a little bit error prone and then you spend half the day trying to figure out why it's not calling it. And if you really dive through their documentation, you're really not going to see any example of them automatically connecting signals and slots. They just assume that you're going to call connect and disconnect. If you're like me, doing this over and over again becomes highly repetitious, boring, and well, it just sucks. Even if you look in their advanced signal slot usage, you can use Lambda functions, but they don't really talk about auto connections. Oh, all right. So we are going to make our own auto connection class here. So I've got some code here. I've got a client. This literally does almost nothing. Really, it just has a testing function and it's going to emit a signal called test, which is going to have a Q string representation of a number. Really not, you know, Nobel Prize winning code here. And then a server, which if we look at the header is just as simple. It's just got a bunch of slots which mimic the client's signals, connected, disconnected, ready, retest, connected, disconnected, ready, retest. So it's almost verbatim the same thing. And we're just got a producer consumer style pattern here where the client's going to emit some signals. The server is going to consume those signals and do something. And we've got a Q object pointer to the sender. I could have literally just said sender. Yeah, it doesn't matter. I did it my way. Let's put it that way. So I did it my way. I just connected, disconnected, ready, read. And they're literally the same thing over and over again. We're just going to say internal from, test from, ready, read from. So I'm just letting us know. I literally could have written this like Q info sender or actually this Q funk info and sender or something like that. You get the point. I could have done something like that if I really, really wanted to. But just in case somebody's downloaded this and they don't understand any of that, I want to make sure it's painfully obvious what's going on. So what we're going to do now is we're going to take the signals from the client and connect them to the server. But I'm not going to write the connect over and over and over again. So what we're going to do here is we're going to say main and let's just do this. We've got those in there and I'm going to make a client, make a server. And then I want to test them. That's right. Whoops. You can call or you can emit a signal while you're outside of a Q object. That's incredibly cool that you can do that. Not something I would highly recommend, but you can do it. We're going to emit ready read client testing. There is a method to my madness. Just bear with me here. And then we're going to say client disconnected. So what we're doing is we're showing that, hey, the client. If you really look at him, we're only emitting one thing from inside the client, this test. However, outside of the client, we're going to emit connected ready read and disconnected. This testing is what emits test. I should probably put emit test. Now what we're going to do is we're going to write a header only class, which I don't often do. And we're going to take that class and make it connect the two objects together. And as long as those two objects are Q objects and follow our naming convention, everything should just work. So I'm going to write auto connect. And this is probably one that I'm going to have a lot of spelling errors. So please be very patient. All right. So we are going to connect signals and slots of two objects. For example, signal tests to slot tests, meaning they have to be named exactly the same. As long as they line up, it should connect them. We're going to include Q object, Q debug, Q list, Q byte array, Q child event, Q meta object, and Q meta method. Remember, under the hood, signals and slots really are just mock generated code. And because they're mock generated, Q gives us all these wonderful little classes we can work with, like the meta object and the meta method. And we can figure out, you guessed it through reflection, what each class has. Wow. That's incredibly cool. So I'm going to say class auto connect. Bang. Now I want public. And this is where I will probably start screwing up really badly void. And I'm going to say connect. See, I lied to you. I said I wasn't going to type the word connect. So now we have a static function here. And I'm going to say I want a Q object, sender, and a Q object. My keyboard is sticking. I hate that receiver. And did I misspell receiver? I did. Shame on me. They need to integrate spell check because I just sometimes do not spell. Well, I don't know why. So we're going to say, if not, sender, return, if not, receiver, return. I want to make sure we have pointers to both objects here. This is where we have to actually do something. We want to get the signals. So we're going to say Q list. And I want a Q byte array, sender, signals. Told you I was going to goof up. And we're going to have to do something here. And what we're going to have to do is create a function that scans them. So let's pause right there. And let's go down and let's create our private static Q list. I said Q list, do my bidding computer. And I want a Q byte array. Let's call this, I'm always horrible at picking names. Let's call it scan type. Why not scan type? And I want a Q object, objecty. Boy, I really misspelled that. All right, Q object, object. And I want the Q meta method. And I want a method type. And that may seem like voodoo magic at the moment. And I apologize. But really what we're doing is say scan an object and look for a specific meta type. Now remember, when we talk about meta, we're talking about data, about data. So this is the data created by the mock, the signals and slots. And we're going to just return a list of them. All right, now we can go back up here and make this make some sort of logical sense here. So now we're going to say, want to scan type. And we're going to scan the sender. I really should pick different names for those. And we want the Q meta. And I want the Q meta method. And we're going to go with signal. So we want the sender signals. And then we can just do the magic of copy and paste, grab this. And then we can say, we want the receiver slots. And we're going to scan type receiver. And we want slots. So we're just going to generate two lists. And now let's actually fill in the scan type here. And let's go ahead and say Q list. And I want the Q byte array because that's what we're going to be making. And I'm going to say list. And if not object, probably should do this first. And I'm going to do this, just return this blank list here. All right, now, if we've gotten this far, we have an object. We need to say const Q meta object. And we want a pointer called mo equal object meta object. So we're just going to get the meta object. So we're saying Q object give you give us your data of data, meaning your meta object. It sounds really confusing, but basically what happens in the background. When you build your Q object, the mock will go in and put a lot of data in there in the form of a Q object. Oh boy, they have some weird naming conventions, but I do absolutely love this. This is just so cool that we can do this. I'm going to say I equal mo dot method offset. And we want I is less than mo dot method count. And in case you're wondering what the method offset method count is, counts pretty self-explanatory. You're going to have a number of things. But the offset is, well, for lack of better terms, this. So if we're scanning for signals, we will have like a public, a few things, and then signals. And that's the offset in the position of where this is. There's more to it. And I'm probably explaining that very badly, but think of it in those terms and it makes perfect sense. All right, so now that we've gotten this far, we've got an object. We've got a meta object. I should probably test to see that we have a meta object. We're just going to return our blank list if we can't get that meta object. And then we're going to say q meta method, because signals and slots are really just methods. And we want mo method and then whatever the count is. Then we're going to say, if method, method type. Now, interesting enough, we're working with the q meta objects. And we could have tried to use like a for each. But ironically, the meta objects don't really have meta data. So it's kind of hard to do things like for each. You can do it, but it's kind of tricky and error prone and I wouldn't really advise it. I've had all sorts of issues in the past. Anyways, now we're going to just say if it matches that type, we're going to list a pen and we're going to say method, method signature, which just is a q byte array, which is basically just going to be a string representation here. Wow, is that confusing, but it's really cool that we can do that. So basically we're taking an object saying, give it a certain type, signal or slot. Get the information about the object, scan through the methods at the offset, and then look for something that matches that type, whether it's a signal or slot, whatever we're scanning for. And if so, append it to the list. Now that we've got to this point, we can just say return our list and life should go on. All right, so we're actually returning a copy. We could do a pointer, but I really don't feel like it. Now we're going to go up here and this is where the interesting bit really happens. We're going to say for each. And in our for each, I'm going to say q byte array signature. And I want in the sender signals. And this is what we're going to do. We're just going to line up the signals with the slots. So we're going to say if receiver slots contains the signature we're hunting for, that q byte array. So if they both have it, and this is what I meant by you must have a test and a test or a signal or a slot. They have the same signature. This is what we're talking about here. If those two line up, then we want to automatically connect them. And then what I'm just going to say q info auto connecting. And let's go ahead and pump this out signature. That way we know what we did. Now I'm going to say q object. And this is where I need to stop and kind of explain some things. We can't really do this connect the way we normally would. Why this part is a little frustrating. It'll take you a bit to figure out, but I'm going to try and see and pay some notes in here. If you dig through the source code of cute. And I really, really hope they don't take this out or they add some way of auto connecting signals and slots for us. If you dig through the source code, you'll see the old school signals and slots macro. So the new way is like, you know, connect and then you give it an object. And then you say, you know, the function pointer, the class, that's the new way. The old way you would actually say signal. And notice how that macro pops up. So really what we're doing is we're kind of back boning off these signals and slot macros. If you look at them, they're really defined as define slot a equals one and pound a and this pound a is just going to print whatever you put in it. So it's slot for one signal for two very, very important. You remember that part. So now we're going to take our connection. And we're going to say, hey, sender. And I want to say two, two plus the signature. And then I want to say receiver. And I want to say one plus the signature. You're probably looking at this going, what in the heck are you doing? Okay, so let's slow down, explain this. So there's multiple ways to connect the signals a lot. And let's just walk through them. So we're going to say Q object connect. And let's say sender needs a pointer, right? And then we're going to say Q object. Whoops. And we're going to say signal and then the receiver and then the Q object slot, whatever that may be. And this is going to give us a horrible list of errors because it doesn't actually exist. But that's the new way of doing it, right? So the old way, and I remember doing this for years and years and years, connect. And you can still do this, sender, signal, and then something like test, and then receiver, and then the slot macro. And that was the old school way of doing things. And it still actually works. But you notice how it doesn't have any error checking. If we try to run this, it will try to compile that even though it doesn't exist. That's why they switched to this newer method of connecting. So really all we're doing is we're looking at the signal and slot macros. And we're saying, okay, so signals puts a two in front of whatever it is. So we're just going to put a two and then the signature. And a slot does a one and then the signature. And the meta object compiler is going to handle all the rest for us. We don't have to do anything else. That is incredibly cool. Let's give this a good build, make sure I didn't type anything wrong. Jump into our main and let's test this out here. So now I'm going to include our auto, maybe auto connect. And then I'm going to say, probably should have done that lower case. I'm surprised it's not complaining at me. I want to say auto connect. And I want to connect the client to the server. Now as long as the signals and slots line up. And when I say line up, remember like the signature test to test. So we're talking connected, disconnected, ready, read, test. Connected, disconnected, ready, read, test. As long as those line up, it should try to auto connect them. Remember our client is only emitting the test. We are emitting them here, the connected and ready read. Anyways, enough talking. Let's see this thing in action. Boom. So auto connecting, connected, disconnected, ready, read, and then. All right. So we got test, test, test, bunch of stuff. So we connected, ready, read, disconnected. So it is working as expected here. That is incredibly cool. So if we wanted to, let's play around with us even further here. Let's take our client and let's get that out of there. Just to show this is working as advertised. So server connected from client, server ready, read from client, server disconnected from client, everything works as expected. Wow. That is incredibly cool that we can do this. Now, my hope, my dream is that we don't have to do this kind of stuff. As cool as this is, my hope is that Qt6, when it comes out, will have some sort of like auto connect class. So you can just say, hey, do this. And this may not be the way you want it. Like you may want your naming convention to be test with like on test or something like that. And that's perfectly fine. You can just simply change it down here in your scan type and make sure that that works. You get your scan types back and then you come in here and it says where it contains. And that's where you would check and you just convert it to a string and do whatever you wanted to do with it. Simple, easy to use, does what it says it does. And we won't ever have to type a signal and slot connect again. Oh my God, that's brilliant. However, for this course, I will not use this. Why? Because I don't want somebody going, I don't understand auto connect. I didn't watch that one video. Can you explain the scan type and what we're doing? So this is the one and only time I'll be doing this. The rest of this course will be using this convention right here unless I'm forced into using, I'm sorry, we'll use this convention here the newer way unless I'm forced into using the older way. But in the real world outside of this course, absolutely feel free to auto connect your signals and slots as long as you can connect them together and it does what you want to do. There's absolutely no problem doing that.