Hi. I'm Jesper Pedersen from KDAB. This might be your very first video with us. I'll bet you. And, of course, if you're one of
the returning visitors, thank you very much for continuing watching us. But if you
are new, I'll bet you the reason why you got here is that you googled "binding
loop." It is like a curse in QML. You get this binding loop and wonder what
is going on?! And, of course, you start googling. Hopefully one day, this video
will hit it above Stack Overflow because, in just five minutes, I will introduce
you to exactly what's going on. Let's look into the example. It looks
pretty ok, doesn't it? We got a rectangle that's black. You
can see a bit of the black pixels here. We got an image that comes out of this
vertical gradient. That's what we have here. Its margin is 5 pixels. That's
why we see a bit of the black rectangle here. And it fills the parent. What's going on over here? Why are there no pixels between the
black line and the edge of my of my window here? Well, let me show you. I take it here and resize it.
There it is -- that dreadful, dreadful binding loop detected for property width
and for property height. What's going on?! Well, let's read the code in a bit more
detail. It goes like this: The black rectangle's
width should be the child's width; its height should be the child's height.
Okay, that's fair enough. The rectangle should be just big enough to
to have the child in there. But when When I look at my child, it says it
should fill its parent. So this is what the QML engine
will see when it's trying to figure out what width and height to give to this element. "Hey, Mr. Rectangle, can you please tell me
what width you'd like to have?" "Oh, hi, yeah. I would like to have the width of my
child." "Fair enough. Hey child, can you please tell me what width you would like
to be?" "Oh yeah, I'm sure I would like a width so I fill exactly my parent." "Hey
rectangle, what? Wait a minute! Didn't I talk to you just a minute ago?" And
there's your binding loop. To solve this binding loop, what we really need to do
is not use width and height. We need to use implicit width and implicit height.
If you come from a widgets background, you will know that this is called size
hint. This is: what would you like to be? Not what are you, but what would you like
to be? And that's what we really want to ask our rectangle. Which size would you like me
to give you? I would like my implicit width to be
whatever and my implicit height to be whatever. So, let's see if that works now.
"Hey, dear rectangle, what size would you like to be?" "Well, I would like to be the size
of my child." "Cool! Hey, child, what size would you
like to be?" "Well, I'd like to be big enough to fill my parent." "Hey, parent..." -- we
still have that binding loop. So, what I really need is to say that the
rectangle's implicit width should be the child's implicit width. It goes like
this: "Hey rectangle what size would you like?"
"Well, I'd like the size to be what my child's size would like?" "Okay! Hi, child,
what size would you like?" "Well, I would like to be the size of my image." So,
it's not returning its width, it's returning the width of the image. So,
the implicit width and the width are now two different things. And the implicit
width is however big that image is. Let's say 300 pixels. And it will say 300.
And then back to the parent, "what size would you like to be?"
"Well, as I said, my child is 300; 300 is fine with me." Okay! Now we're in business. And then the QML engine will go to the
rectangle and say, "Hey, by my genius, I came up with the idea that you should be
300 pixels wide." And the rectangle says, "Okay. I'm 300 pixels wide."
Now, the binding loop down here at anchor.fill makes the child say, "Okay. My
parent's width and height (whatever) changed. So, I better fill them." And we do
not have that binding loop anymore. And if I run it, we'll see
down here no binding loop. And the color is all the way to the edge. Why wasn't it all the way to the edge before? Well, because QML didn't give up and just
segmentation fault. It tried its very best, but realized it has a binding loop. So, it
was actually one value behind in the calculation. If you're not entirely sure
you understand what's going on yet, it might be time for you to go in the
description under this video and follow the link to the video where I'm talking
about by property bindings. Because that's exactly what's going on here. A
property binding for anchor is really just a property binding on width and
height. So, let me try and write these two lines here with width and height instead.
So, it says that the width of this down here should be the parent's width. Well, we
have the five pixels of margin on both sides. So, there we are. For the height, same
thing: parent.height - 5*2. The x should be 5; the y should be
5. If we now go back to the version where it did not say implicit,
but said width and height. And it did not say implicit width, but just width. It did not say implicit height, but height. Then, it's easy to understand,
right? "Rectangle, what width do you want?" "Well, I want my child's width." "Child,
what width do you want?" "Well, I want my parent with -10." "Ok, parent, what..." -- and
now the the binding loop is obvious, but it's hidden there behind the
anchoring that is going on in child. Hopefully, those 5+ minutes help you understand about binding loops. Next time you see a binding loop, all you
need to think of is my anchoring is really just updating my width, height, and
x and y. And instead of using width and height, I need implicit width and implicit
height. The next video, which is going to be the last one in this module here,
will be about colors and gradients. So, stay tuned. And until then,
have a great time!