Introduction to Qt / QML (Part 44) - QVariant

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi. I'm Jesper Pedersen from KDAB. We are going  to sing a song for one of the unsung heroes   in Qt, the class QVariant. Let's  look at some code right away, shall we? In this code, we have data. It's  an union with an integer, a double, and a char.   In my classes, I always ask the students when  you would use a union and I have a lot of   hands coming up. In every single class, one of those  people will tell me, "Well, see, a union is this   data structure where you will only allocate as  much memory as the largest element in that union."   It's, of course, entirely true but it was not what  I asked for. I asked when you will use the union.   So, now we got that out of the way. When will you  use a union? Well, you use a union when you have   some function where you return a value that can  be different depending on what the function did.   So our typical example of this is a parser  where the first step of passing is to read   the input file and it does so by tokenizing  the file. So it will read int, that's a token,   then it'll read I, that's a string, and then we  read equal to zero. So, the zero part is a number.   So, depending on what it will read, it will  return a different value. It'll do so in a union.   That's great. That is when you would use a union.  We'll see that in at least two different cases   in this training. The last case we're going to  see is our model/view, where we have the models   data method returning a variant,  and the other case is our property system   we're going to see in the next video.  And with our properties, we're gonna   either return from C++ level a  integer or a string or a color or whatever,   and all of these different ones go  into a union and return to the QML level. Let's look at this code again.  What is the problem with this code?   There are actually two problems. You  can press pause now and think of it. Problem number one, and I'll bet you that in most  cases where you have used the union you have tried   to solve that problem yourself. Whenever somebody  gives you a union, you cannot look at that union   and say, "Hmm okay, so you put in an integer." Well you  need some enum, likely. So your unions are likely   wrapped with an enum. So you'll have a structs around your union and together   with the union you will have an enum and the enum  tells you, "Well, I put in an integer, I put it in a   string, or I put in a whatever." So that's problem  number one. Problem number two is even worse.   Line number five and a half -- I cannot highlight  that here but it's the line after number five.   Pretty clever, huh? Line number five and a half -- I would  like to have my own data structures in there,   but sorry we are closed for business. No more  data structures in here. "Jesper, what's up with   you now? What do you mean? I'll just press  enter in my text editor and it's in there." Yes, that's what you would do, but which file  would you do that in? You would do that likely  in some file deep inside the Qt code if  you want to support your own data structure.   And what does that mean? That means that every  single time somebody needs to use your software,   they need your special version of Qt. And every  time a new version comes out of Qt, you need to   patch Qt. Are you really up for that? I don't think  so. Now let me show you a union. I actually brought   one today. So, here is my very beautiful union. A union is this thingy that I can put stuff into.   Once I put stuff into my union, I don't know  what's in there but I can open it up again.   But in the variant compared to the to the union -- actually, whenever I open it up, I can look   into it and it will tell me what data type I  put in and, furthermore, I can extend my variants   so that I can add new data types for it. Let's  see how that works in code. QVariant is a class   that lives in QtCore. So, if I'm talking about  the QtCore classes, I can construct my variant   by simply using a constructor that takes the type  that I'm interested in. So 42, here, has a parameter   to the constructor for a variant. Now I have a  variant that has 42 wrapped in it. I can go and   get that integer out of my variant again by going  to int on my variant. And here is your integer back.   I can go and ask my variant what type  is in there and it will tell me as a string,   "Hey, this is an integer." "i-n-t," that's  the string that will return to me.   Let's just go here to the documentation  in Qt Creator and look at QVariant   and you can see there are quite a few different  constructors that each take a different   type here. So we've got QModelIndex. Well, we're  going to see that when we talk about model/view.   We got EasingCurve; we've seen those.  We've got regular expressions. We got   rectangles and lines and so on...sizes and...You  can see there are actually quite a few of those.   But it's only those classes that are in QtCore, and one of those that is not in QtCore is a   color. Color actually lives in QtGUI. So, to  be able to read the color, I would need to do it   slightly different. I would need code that looks  like what we have down here. So, I got a QColor.   That is the red color here. I constructed my  QColor from the enum Qt::red. So I got a   QColor here and I need to convert that into a  variant. I need to say QVariant::fromValue, less than QColor greater than -- but the C++ system for template overload is actually   smart enough so that I do not need to write that -- and then the QColor here. To get my color out of   the variant again, I need to go variant.value.  And this time there is no parameter here that it   can use to decipher what the template  overload is. So I need to do that extra sit:   less than QColor greater than and then  open parenthesis, close parenthesis. And I can   again ask what type is in there and it will tell  me, "Hey, it's a QColor." So my type is as foreign   to QVariant as QColor is. So, the question  is: How can I get my type into a QVariant?   I'll show you. All I need to do is  declare my type. It's a contact in this setup here.   My type needs three things: it needs a default  constructor (that is a constructor without any   parameter), it needs a copy constructor, and it  needs an assignment operator. But if it has those   three parameters, all I need to do is to write Q_DECLARE_METATYPE. I do that   in my header file, open parenthesis, whatever  my class is called, close parenthesis. You see   that down here on line 13, Q_DECLARE_METATYPE.   And now, once I've done that I can take my variant.   I can put it into it. I can take my class and put  it into a variant. I can read it out of a variant.   We're not going to see this for our own classes  in the next video, but we're definitely going to   see that when we talk about model/view. So, stay  tuned until then. And, in any case, now you know   you can put your own data structures into QVariant  and that is actually a nice thing to know. So,   shall we have three hoorays for QVariant? Hooray!  Hooray! Hooray! Yeah. I'm Jesper Pedersen, from KDAB.  I'll see you next time, when we'll talk  about how the property system is implemented   in QML. Until then, have a great day.
Info
Channel: KDAB
Views: 2,412
Rating: undefined out of 5
Keywords: C++, Cpp, QML, Qt, KDAB, QVariant
Id: SjeDUrC9YRo
Channel Id: undefined
Length: 8min 46sec (526 seconds)
Published: Tue Dec 22 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.