 Hey everybody, it's Brian, and welcome to the 35th Qt Tutorial with C++ and GUI programming. I wanted to kind of wrap up our threading for a little bit. No, we haven't gone over everything, but the rest of the stuff on the threading topics are more advanced. So I kind of want to call this the basic threading tutorial, and we'll call this part six, and this will be the last of the basic tutorials on threading. Okay, I have to back up a little bit. I had posted some comments in the official Qt forums and in Qt Center. Basically, it sparks some conversation on how threading should be done correctly. Now, if you go into the help and type Qt thread and you get the Qt thread class reference, and you click more, you can see that Qt's own documentation says to subclass Qt thread. And you can see here you've got class and you've got a subclass of it and you're overriding run. So that's why a lot of people do that. Now, some people out there have said that's not the way to do it. That's not correct. And there have actually been some disagreements in these various forums that I've been reading for the last couple of days on how to do things. So what we're going to call this is how to do a thread correctly in Qt. And if you go to, and you can actually read part of this, if you go to blog.exys.org slash entries slash 2010 slash Qt thread underscore affinity.html. I realize it's a long link, but you'll get this very, very nice how to on threads and why this is done incorrectly. See affinity mistake and he talks about how you make a subclass and it's not correct. And then he says doing it right. And I'm going to summarize the whole thing for you in case you don't want to read it. It says the easiest thing to remember is never put a Q object on a Q thread because a Q thread is not an object. Basically, it's all you need to know. And what he says is you have a worker and you have a main thread and you have an object and you move it to a thread. And we're going to kind of build a real demo, very simplified demo application. The problem with threading is it's very hard to come up with an example in 10 minutes or less in real time. So I want to try and keep this as easy as possible. So let's go ahead and close that. Let's just jump right in. And we are going to make a new console application. And we'll call this threads done right. Put it in your usual location. Next, next, finish, finish. And we get our just normal app. So first thing we want to do here is actually add a new class. So we're going to say a new C++ class. We're going to call it my thread. I'm sorry. Let's not call it my thread. Let's call it my object. That way, we don't get these confused. The base class is going to be QObject. And let's just hit Finish. And you see how we now have a class that is a subclass of QObject. So we're not subclassing QThread anymore. Now, we've got a little bit of work ahead of us. And I'm going to kind of whip through this really fast, because believe it or not, when you're recording 10 minutes goes by very quickly. So let's just add our includes here. And I have to apologize if my typing is atrocious. I'm trying an experiment with my vision. I wear glasses because I'm nearsighted. And I'm going to try and wean myself off my glasses, because my vision has been progressively getting worse over the years. My daughter thinks I'm just a total moron for doing this, but I really don't want to wear bifocals. And I dread the thought of getting eye surgery. OK, now we need a slot. I'm going to say void, do work. And let's actually make another one called or not a slot. Let's make a function called do setup. And setup takes a QThread. I should say a reference to a thread. All right, now we've got our basic header here for our class. And now we need to actually implement this. And let's go into the implementation file here. All right, now let's say void my object. And if you're kind of wondering what I'm doing here, let me explain really, really quickly. What did I call that option? Kind of lost myself there. What we're doing here is we're setting it up so that we're going to pass a reference to this thread. And we're going to connect signals and slots to it. And the reason why we're doing that is because we want to start this object on a different thread without actually subclassing the thread. Sounds really confusing, but I promise you, towards the end of this, it'll all make sense. Took me a little bit to figure it out too. But it really, really, really worked. So connect. And first thing we're going to do is say thread. And the signal is going to be started. So what we're going to do is we're going to connect when the thread is started. And we're going to connect it to this. And we're going to say slot. Hope if I could spell. And the slot is going to be do work. Remember that slot we created, which we are now going to implement here. So we'll say void. My object, do work. So in short, once the thread is created, it's going to call this slot right here. Or I should say the signal will be admitted, and then the slot will be generated. And right here is where we will do some of our work. Let's say 4 int i equals 0. And i less than, let's say, 100 QT bug. And let's just send some information out here. And whoops. Very simple. Now, let's actually just build this. Make sure we get a clean compile out of this. And it compiled. So let's go back into our main. Now we need to connect everything all together. And this is where the actual work is going to be. So we need a couple of includes here. Because we're going to create a Q thread. And then include. Jeez, maybe I should have worn my glasses. My object. I wonder how many of you out there have actually tried to type without wearing your glasses. I thought it would be easy, but it's actually quite a challenge for me. Q thread, we'll say C thread. So we're just going to make a thread object. And then we're going to make a my object. And now we're going to set it up. So we'll say C object. Oh, what did we call that? This is what happens when you get older kids. Your memory goes away. Do set up is what we called it. So do set up. And we are going to basically just pass it the C thread that we just created. And now we're going to call something, which is the part of the Q object class. And it's move to thread. This is where the real work happens. This is where the real magic happens here. And you notice how it takes a pointer. So let's actually just hand it the address. And now we need to start that thread. So real quickly, before we run this, let's kind of go through this really, really quick here. We are creating a thread. We are creating a my object class, which is just a sub class of a Q object. And then we're calling this do set up. And we're handing it the thread. And when we go into do set up, really all we're doing is we're just connecting the signals and slots. We're saying, hey, when that thread emits the started signal, connect it to the do work slot. So when the thread starts, we're going to call do work. Now, here's where the magic happens. Move to thread. What we're doing is we're saying, take this object and move it into this thread. That way you're not subclassing the thread, but you're moving it to the thread. Now, why would you do that? I mean, we've always subclassed the Q thread. And it's worked fine. Well, from some of the discussions I've read, and I'm sure many, many of you will correct me if I'm wrong, signals and slots are not meant to be run with Q thread, which I find interesting because Q thread itself admits signals and et cetera, et cetera. But this is the correct way of doing it. And then, of course, you run the thread start. And when you call start, the signal's emitted, the slot's called, and the code runs. So let's compile and run this. And if everything goes good, sure enough, it ran. Let's actually slow this down just a little bit. I don't know about you, but I really like seeing things work, so we'll call MSSleep. We can't do that, can we? Why? Because we don't have the context of the Q thread object. So what we'd have to do if we wanted to call thread, which I'm running out of time, so I can't do, but we would just keep a reference to this thread object, and then you can make the thread sleep. So well, I'm sure you have many questions. I know after reading all those tutorials, I was kind of left bewildered wondering why is this the correct way of doing it, and the Q thread subclass is wrong. Even though I've read three books on Qt programming and the official documentation even says to make a subclass. Well, the only answer I can give you is this is really a testament to how flexible Qt is. You can just make it do just about anything you want. And it's very flexible, and it's very strong. I have yet to actually crash Qt, where I have crashed the Java framework, and I've crashed .NET many, many, many times. So anyways, this is Brian. Thank you for watching. I hope you found this video educational and entertaining. And we're going to step away from the threading for a little bit and go back to some gooey stuff. And we'll come back to threading, I should say advanced threading later on.