 Thank you. So who finds this annoying with the title not quite fitting properly? It's sort of things quite easy to write and the problem of QML is very easy to write Which means people who shouldn't be writing code tend to write interesting QML so about me I work for a company called Blue Systems and I'm sponsored there to work in KDE and I spend most of my time Working in the downstream projects fixing Upstream code, so I work for a distribution fixing things out along in plasma So I see a huge amount of code That's not my code I have to go and fix it and it's the same mistakes coming up over and over again so quick talk just coming over three of the most common things that I always see again and again and It's so easy to capture review times if you know to look for them I had one person in the review asked me what QML lintway was using to find this mistakes. It was just reading So what makes good code? It's obviously subjective. I mean some people like it being faster, right? people like languages are faster, right and Languages that perform well is good. It's a code that runs super fast. That's good and code of awesome particle effects There's some in the background but a very faint probably stuff. That's also good but It's a good code Important thing for code in my opinion, which I'm now sharing is readability. Is this ancient Roman proverb? It's on their MSDNA website code is read more often that is and more often than it is it is written So writing is an important part is how easy it is for somebody else to read it because people read that code Again, and then again and again, even if you're not not touching that particular code They'll be touching code near it. They need to understand that original code And there's an extra partious quote that says it may even be you in 12 months time And you'll have completely forgotten your code and you need to relearn it So you need to be even read your own code so readability is very important and that's what we want to focus on and another quote That's mine Good code is code is still works after somebody else edits it because anyone can write code at work. You test it it works But it's a different in quality if somebody else can edit your code and then it still works and it kind of reflects well on you So I'm gonna do an example of a very small app and the source of thing that can go wrong So this is an awesome app based on one of the cute examples from the website There is a button and I'm gonna have to try and click it on this green. It's a good application. You can clap if you want Brilliant app, let's look at a code for that. We have a text box. It's got an ID says message box awkward Okay, and then we've got a handler and because we have auto completion typos get copied across We're saying massive box again, and we're training a text So now that's a common piece of code You all understand you all agree. I was gonna work. We saw it work. That's some lovely code in another person's gonna come along maybe you and Our buttons now complicated. It's got some more particle effects in it. It's got accessibility handling. It's now 200 lines of code So someone's gonna come along and split it into a separate component So now your main dot QML file looks like this we have the text box with the ID Which is wrong and we have our component my button dot QML But our handler is still here. We still have this little code that says on click massive box of text equals Ivan click and That still works because the way QML component scopes works because this component is created by a component It has access to all the pop IDs and the root properties of column It will still work and if I want to run this code, it will still work. That's a lovely commit however, Sebas comes along and He's noticed that typo So he opens main doc QML. He sees this. He changes it He does a search in that file for any other users of that ID and he commits it Well, you can do it with you because even every reviewable tool we have review board or garrison fabricator They show you a difference of code and this file Even if you search all of this file, you're not going to see a mistake because The ID is not mentioned in this file only once So it's broken So which commit caused it to break The fact that you change the ID to now be correct or rather Was it broken when somebody split that component and left this interlinking dependency between files? And I would argue for the sake of readability When you split files you want to avoid this interlinking dependencies between them because it causes problems And the main problem it has is now instead of just editing out one file All I need to know is that one file I can search in that file. I can pretty much memorize one file But when you have interlinking files, you have to memorize Every single file in your project in your head at once and know which ID is linked to where and Every time you're ready to file You have to do incredible get magic and grepping to try and find where it could possibly be used and This slows down your development Considerably and it can introduce those sort of subtle bugs that we saw in that very very simple application that one very small fixing a spelling mistake and My amazing acting to know that that wasn't deliberately put there Causes these problems and it does come up quite often Typically not in something as simple as this but an is statement which is now referencing something which is undefined You don't even see a warning on it. It will just pass by Unbeknownst to you your code is no longer working and you won't notice for several months until you get a use report That is obscure feature is broken So what's a good policy for avoiding us? We know when we split out a component into my button.qml. It could still references IDs and properties from a component that created it, but that's not a good practice. It's very simple But it leads to problems. So how do you fix it? if when the person split out your button they added a signal on the root and Obviously pass the signal from the mouse and mouse area to your root Main.qml now only references files within itself. You still have a dependency on the public header of button you still depend on anything any of your root properties But that's no different to using any other component. You don't have that interlink that's going bidirectionally between the two files So what we've done is moved all your logic that reference IDs from a component into being within the same file and That is considerably easier to read and it won't break as often So that's one of the take away things from this talk Is only reference IDs within the same file ideally? Yes I mean Yes, but that's a lot easier to grab for because now all we're searching for every time you change my button You'd search for users of my button and that's something that you can search for Where searching the other way is backtracking doesn't work So it's something solvable and that's something I would comment on review if you change a public API of a product There is no concept of public and private API in QML But it's good to keep the root properties are handled differently and this kind of does happen the other way around if If inside my button we're now setting a text. I now have I have a text inside my button I'm referencing an ID again. I'm referencing an ID inside a component. That's not mine You can also get to the same problems somebody else where did my button pardon okay, and You get the same problems again. You're still referencing. It is my ID with a button text You're referencing IDs in another component and so the problem goes both ways So again fixing it It's a good idea to always move any properties that an external component wants to edit into being one of your root properties Because that means you only have a small subsection of things to worry about when you change And that limits the amount of time to go and break it either deliberately or accidentally So when using QML only reference components Properties are in the root of a component and when writing components try and put anything you're going to want to change as a root property and property alias is a really useful System I assume most of you know it. You're not actually declaring a new property You're just saying it was a property called this and it every time you set text It will implicitly change the text of this ID here So that's everything I wanted to cover with regards to good components. You want to write it as though they can be used independently and Making no assumptions about how we are currently used because how we are currently used can change right every component is though it's a library and Weirdly people do that for small things for buttons ever-known mistakes as soon as a project gets bigger Soon as a big component people seem to think you've also Applied so more complex it is and more people make it more complicated, which is bizarre So general rule for referencing ID outside a component move some logic somewhere And you should be able to open any component anywhere with QML scene That's a good rule of thumb and if you've got context properties you can fake him with a dummy data folder So any of the components should be able to be opened independently of QML scene and that helps your unit testing If you have the interlinking you can't write unit test properly So that was everything for components Item geometry is another place where we often see quite a lot of mistakes in general Each axis horizontally or vertical should have either two anchor points defined defined like a left and a right or a left and a width or An X and a width all be managed by layout But never two of those at once. So I'm going to give some bad examples We have an item your focus go it has a Left it doesn't have a width which means this rectangle here, which is filling a parent will be completely invisible And that's a quite a common Thing to do and when you review and code every time you see an item to check it has all of the geometry set And it's quite an easy thing to review And this is another common thing I've have seen several times where people write anchor left anchor right and they set a width Warm of those isn't going to do anything And most you know QML will know anchors get evaluated afterwards But it's still unreadable code because I look at this code and I would think oh, but that width is 100 When in fact, it's not it's an undefined value and finally another thing that we see a Row layout will modify a position of items. So this item is trying to change a Left anchor and the left a left anchor changes the X of an item a row layout changes the X of an item You have two things trying to change the same property at once and if you have two things trying to change the same property at once you will either get Warm of them not working or you'll get a recursive loop of doom and Recursive loop of doom is something you generally want to avoid that's probably worst case. Yes, and That's why some geometry if you want to make sure you have all of the geometry set for every single item Text in a box. This is where people get confused quite often. I think or something comes up So going back to before we have a text just an example ever text with a top anchor and left anchor and some really really long string What's going to happen when it's placed in a box of a fixed size? It's going to overflow that looks rough however Here we have we're setting all your geometry. We're setting a left point. We're setting a right that point The text should be constrained within the box, right? Yes, it looks like this and the reason this happens is because although you've told it the size of the text ends here You've also told it. It needs to display as much text So you have this interesting quirk at your item ends here, but it just carries on drawing anyway Which probably isn't what you want You can set clip in the box But generally that might not be what you want either. I mean you've got a vertical space. We want to wrap so we've added wrap mode So now what's going to happen? Now it overflows at the bottom and that's not much better So in this particular case if we have a box of a fixed size which isn't growing to your content Which does happen if you've got imagine a list here or something such You want to word wrap and the lead? The rules and then it looks perfect now. That's what we want my text so you probably want to set a width on the text or Grow your container to always fit a text but given you don't know how big a text is going to be Particularly with German translations. It might not fit in the user's window anyway So if you can't guarantee a technical fit horizontally Word wrap or a lead and if you can't guarantee a text will fit vertically you want to elite and One thing I have seen before People thinking a lead and word wrap are somehow mutually exclusive They are if you've only got one line But in general we're not and I don't want to show this code because it made me cry It's a bit of code I saw in Platinum. I said turn on a leading if we were going to overflow your box And that's pointless because that achieves absolutely nothing because if it wasn't going to overflow your box It wouldn't lead anyway. So now just a remark And this goes back to what we saw in a title Centering text when people want to send to the text people think he should set us a center anchor Because you want to set that item in the middle And that's not a good approach because it leads to what we saw in a title slide It just overflows and even though what we set word wrap We haven't constrained a width So it would just overflow and there is a solution You could explicitly set a width for the text to be either size of the text or a size of the box But that just gets complicated A better way is to reinvige in how you imagine text don't position a text where you want a text to be That's a amateur mistake. You want to position a text where a bounding box of the text should be so imagine in word When you made an awesome word art You click and drag a box and our box says the buck this area should be full of text You don't want to say where a text itself is you want to imagine you're dragging that box in Microsoft Word Or leave off it So don't position a text position the bounding box and then within the bounding box There are properties in a text object to position the text inside it Just gonna have a yeah, had me gulping mic top Sorry about that. Okay Final thing that I want to cover width versus implicit width because it seems is something That's quite easy to get confused over because it's quite confusing So turning it from How cute describe it into words that I think are easy to understand with it's a size an item currently is an Implicit width is a size an item Wants to be like if I could be any size That's how big I want to be I get a lot of spam emails which are basically the same as just a size an item I Want to be so typically speaking The width will be defined by a size of your window because it uses dragging a window or a size of a scroll view And it will be passed down from a parent to a child which will pass it down to its children Which will pass it down to its children Whereas the implicit width a size an item wants to be a size a window should be goes upwards We take a size of Textbox work out how big a margin should be a certain implicit width with a button And then that buttons next to some other buttons and these implicit widths go past upwards for your change So it's based on implicit size of your children and gets passed upwards So directionally speaking width gets passed down implicit width gets passed up and obviously height is the same So an example of going back to a button because we all have buttons for examples buttons and qml are platinum's equivalent of clocks We use them for example to everything We have an image maybe some little icon that would tick mark or something and we have our text And we want to work out implicit width of the button We're setting this image to a thick size so we know how big it is going to be We know it's got some margins So we know it's going to be 20 pixels. It's always going to be at least 20 pixels up until the end of the image But we don't want to Say a width of the button is a width of the text We want to say a width of the button Width of the button should be The size of text wants to be the size of text wants to be in order to fit So it's we take the implicit width of the text because the text can change. This is dynamic the image is not dynamic The text is And then a little margin on the end. So that's a good example of how to write implicit widths But generally speaking A lot of your qq quick components will do this for you Row and row layout will automatically calculate implicit width using row and row layout Is so much easier than anchors for anything straight forward loader also sets implicit width And if you're not sure whether to use width or implicit width Width is by default bound to implicit width So if you're only going to implement one implement the implicit width because then When somebody else changes your item you're implicit when the information is still available Whereas if you only set a width attribute if somebody else changes your width attribute Your information is lost and you don't ever want to lose information Um pretty much near end. Okay, so I'm getting bored Countdown A row will reposition items A row layout will reposition and resize items So if you want the size of items to change Use a row layout if you just want items to be positioned use a row and that's General just difference because I've seen people Getting confused over that before and we sometimes use row layouts a bit overkill Final slide binding loops Reasons you have a binding loop warning in your code You have a binding loop Here shouldn't any component also then have implicit width implicit height set by default Um, I think so. I think that's generally a good advice. I mean except for your item itself Um, you'll find most cute Components do I think it's a good strategy to get yourself into even if you're not using it now It's something that might be used later because right now if I make Like a little widget to show the spinner or something I might know it will always be set by a parent component But It might not in future So I think it's generally a good habit to get into particularly if you've got anything dynamic inside that component But implicit size on its own doesn't do anything. It's not a property. It does anything It's just sort of metadata for for your item Yep Oh, you can shout I can repeat it Oh, yeah, anchor still parent on a root item is is generally bad because you want a geometry to be managed in a way You can read and if an item manages its own geometry You'll get yourself You can't you don't when you're reading the code which creates the item You don't know where that item is going to be So I would say you don't want to do an anchor dot fill on any item I think I did in some of my snippets because I was trying to show that it was just a snippet Rather than adding an item on top Wait, wait, oh, hold on You have technology um We had technology Well, sorry Okay, it's all good. Okay. Um, I have a qmel component which has an implicit size. Yep And now I want to change Something dependent on if the width property is set from the outside So is if If the parent doesn't set width then the behavior you have that implicitly implicitly, um, if you set an implicit width on a component If the width is set externally the width set externally will apply However, if the width is not set externally width is by default bound to your implicit width So it will use the implicit width. So you get that whole concept of I want to use my size Unless it's been set externally. So if you set an implicit width, you will get that feature And I can check if I, uh, do something like if width unequal to implicit width, for example, or I mean, I don't I think there's always saying you don't I don't think you need To I mean if in general in your inside your component If you want to be using width because you don't know how big you actually are Because as I said width gets passed down from your parents. So any items inside your component should be based on the size of your parent Not implicit size of your parents because you might not be at implicit size So I think in general, I don't know your specific case But in general you want to base base it on your current size rather than the size you want to be The case is I have a button which should do its resize Based on the actual text that is set on the button But I I want to feature that the parent can say You button you are you have this size. Okay, and the text should elide or web or if you set your text to a lead And then you set the button to have an implicit width based on the implicit width of your button You will find that by default If it's not set externally the button will set felt show Entire text because the an implicit width of some text is the size of the text but if it's been set externally then You'll be shrinking a text and then it'll be a leading So you want to imagine that you could be a leaded set a lead to true But then pass up your implicit width to say I want to be as big so I don't have to elide I have a QM off. I'm going to show you actually So this is implicit width of text Because implicit size of the text is quite Interesting really Implicit width of the text Is the text it would be if it wasn't wrapped and elided So even if you wrap and elide the text implicit width is saying how big can I be in order to not wrap? And then the implicit height Is based on how high should the text be assuming I'm wrapped because about to set in order to not elide And it's treated to almost Completely independent things because you don't want to set it to implicit width and implicit height because That blue box shows implicit size but There's no point setting a text box so it's in full implicit size because that's both long enough To not Not wrapped and long enough to not elide if it was wrapped So you can mix and match them interchangeably horizontally and vertically don't they have to have the same style applied Okay, one last question You said that if the warning I have a binding loop Occurs I have binding loop But how to avoid a binding loop if I have two controls That set a value and also should display the value like for example in a calendar widget Where I can type in the date or I can select the date by clicking on Day for example, I don't know All of your code. I can't say but in general most binding loops can be avoided by saying Use of implicit size and size independently So you're saying I want to be as big but that's not relevant on my current size And then you don't have a binding loop because you don't have my sizes based on my current size, which is effectively what a binding loop is um I've never seen a false positive There's always been a way to avoid it or it's been a false or something that I can't control But we can at least identify it. I I can't comment on your specific case. Maybe catch me afterwards Thank you everyone and thank you David for his nice talk If you have more