Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Some questions on a QML transformation project
Forum Updated to NodeBB v4.3 + New Features

Some questions on a QML transformation project

Scheduled Pinned Locked Moved Solved QML and Qt Quick
17 Posts 2 Posters 4.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • tomyT Offline
    tomyT Offline
    tomy
    wrote on last edited by
    #5

    Thanks for your info.

    1 Reply Last reply
    0
    • tomyT Offline
      tomyT Offline
      tomy
      wrote on last edited by
      #6

      Hi,

      In the Transformation.qml file we have:

      import QtQuick 2.8
      
      Item {
          width: bg.width
          height: bg.height
      
          Image {
              id: bg
              source: "/background.png"
       }
      
          MouseArea {
              id: backgroundClicker
              anchors.fill: parent
              onClicked: {
                  circle.x = 84
                  box.rotation = 0
                  triangle.rotation = 0
                  triangle.scale = 1.0
              }
          }
      
         ...
      } 
      

      First the part

      Item {
          width: bg.width
          height: bg.height
      

      seems useless because if I remove these and make the Image as the first item, the program runs with no changes. So what need is there for that please?

      Neither id: bg nor id: backgroundClicker in the code seems to be needed as well.

      Also I modified the main.qml code to:

      import QtQuick 2.8
      import QtQuick.Window 2.2
      import QtQuick.Controls 2.0
      import QtQuick.Controls.Styles 1.4
      
      Window {
          visible: true
          width: 700
          height: 600
          title: qsTr("Transformation")
      
          Column {
               spacing: 20
      
           Transformation {
                   id: transformation
                 }
      
           Button{
               Text: "test_overlap"
               style: ButtonStyle
               onClicked: transformation._test_overlap()
                }
      
           Button {
             Text: "test_transformed"
              style: ButtonStyle
              onClicked: transformation._test_transformed()
            }
      
           Button {
              // Text: "Quit"
               onClicked: close()
           }
         }
      }
      

      Using only

      Transformation {
                  id: transformation
                }
      

      the program runs through a process, but what are its steps briefly, please?
      I also tried to add a text and style to the buttons declared above. But got errors!

      E 1 Reply Last reply
      0
      • tomyT tomy

        Hi,

        In the Transformation.qml file we have:

        import QtQuick 2.8
        
        Item {
            width: bg.width
            height: bg.height
        
            Image {
                id: bg
                source: "/background.png"
         }
        
            MouseArea {
                id: backgroundClicker
                anchors.fill: parent
                onClicked: {
                    circle.x = 84
                    box.rotation = 0
                    triangle.rotation = 0
                    triangle.scale = 1.0
                }
            }
        
           ...
        } 
        

        First the part

        Item {
            width: bg.width
            height: bg.height
        

        seems useless because if I remove these and make the Image as the first item, the program runs with no changes. So what need is there for that please?

        Neither id: bg nor id: backgroundClicker in the code seems to be needed as well.

        Also I modified the main.qml code to:

        import QtQuick 2.8
        import QtQuick.Window 2.2
        import QtQuick.Controls 2.0
        import QtQuick.Controls.Styles 1.4
        
        Window {
            visible: true
            width: 700
            height: 600
            title: qsTr("Transformation")
        
            Column {
                 spacing: 20
        
             Transformation {
                     id: transformation
                   }
        
             Button{
                 Text: "test_overlap"
                 style: ButtonStyle
                 onClicked: transformation._test_overlap()
                  }
        
             Button {
               Text: "test_transformed"
                style: ButtonStyle
                onClicked: transformation._test_transformed()
              }
        
             Button {
                // Text: "Quit"
                 onClicked: close()
             }
           }
        }
        

        Using only

        Transformation {
                    id: transformation
                  }
        

        the program runs through a process, but what are its steps briefly, please?
        I also tried to add a text and style to the buttons declared above. But got errors!

        E Offline
        E Offline
        Eeli K
        wrote on last edited by
        #7

        @tomy

        width: bg.width
        height: bg.height
        seems useless

        In this case they may be useless and in general when you write a component (a qml file) you shouldn't explicitly give the top level item's height & width. It's a good habit to give implicit size instead. Unfortunately those things are a bit complicated but in short, width and height may be calculated by the engine and may differ from what you explicitly give. Implicit width and height are some sensible size which the visible component could have if it's not for example stretched to fill available space or if there is no explicit size given.

        IDs are necessary only if the object must be known by name somewhere, but it may still be good for self-documentation. Come up with a descriptive name for an object and you may thank yourself later when you read your own code because you will know without further thinking why you have made the object.

        import QtQuick.Controls 2.0
        

        means that Controls 2 are used, not Controls 1. Change it to

        import QtQuick.Controls 1.4
        

        and you can use styles. I think that the qmlbook uses only Controls 1. I tend to use Controls 2.

        Button{
                 Text: "test_overlap"
        

        must be

        Button{
                 text: "test_overlap" // property names must always begin with lower case, Text is a type name!
        
        tomyT 1 Reply Last reply
        2
        • E Eeli K

          @tomy

          width: bg.width
          height: bg.height
          seems useless

          In this case they may be useless and in general when you write a component (a qml file) you shouldn't explicitly give the top level item's height & width. It's a good habit to give implicit size instead. Unfortunately those things are a bit complicated but in short, width and height may be calculated by the engine and may differ from what you explicitly give. Implicit width and height are some sensible size which the visible component could have if it's not for example stretched to fill available space or if there is no explicit size given.

          IDs are necessary only if the object must be known by name somewhere, but it may still be good for self-documentation. Come up with a descriptive name for an object and you may thank yourself later when you read your own code because you will know without further thinking why you have made the object.

          import QtQuick.Controls 2.0
          

          means that Controls 2 are used, not Controls 1. Change it to

          import QtQuick.Controls 1.4
          

          and you can use styles. I think that the qmlbook uses only Controls 1. I tend to use Controls 2.

          Button{
                   Text: "test_overlap"
          

          must be

          Button{
                   text: "test_overlap" // property names must always begin with lower case, Text is a type name!
          
          tomyT Offline
          tomyT Offline
          tomy
          wrote on last edited by
          #8

          @Eeli-K
          Thank you.

          you shouldn't explicitly give the top level item's height & width.

          Did you mean "the top level item height & width", please?

          IDs are necessary only if the object must be known by name somewhere, but it may still be good for self-documentation. Come up with a descriptive name for an object and you may thank yourself later when you read your own code because you will know without further thinking why you have made the object.

          Yes, you're right. Thanks.

          import QtQuick.Controls 2.0
          

          means that Controls 2 are used, not Controls 1. Change it to

          import QtQuick.Controls 1.4
          

          What does it mean please, I can't understand well. Isn't Controls 2 used? Where is it stated?

          // property names must always begin with lower case, Text is a type name!

          Good info.
          And when I use that style for the buttons, they won't be appeared on output!

          E 2 Replies Last reply
          0
          • tomyT tomy

            @Eeli-K
            Thank you.

            you shouldn't explicitly give the top level item's height & width.

            Did you mean "the top level item height & width", please?

            IDs are necessary only if the object must be known by name somewhere, but it may still be good for self-documentation. Come up with a descriptive name for an object and you may thank yourself later when you read your own code because you will know without further thinking why you have made the object.

            Yes, you're right. Thanks.

            import QtQuick.Controls 2.0
            

            means that Controls 2 are used, not Controls 1. Change it to

            import QtQuick.Controls 1.4
            

            What does it mean please, I can't understand well. Isn't Controls 2 used? Where is it stated?

            // property names must always begin with lower case, Text is a type name!

            Good info.
            And when I use that style for the buttons, they won't be appeared on output!

            E Offline
            E Offline
            Eeli K
            wrote on last edited by
            #9

            @tomy

            Did you mean "the top level item height & width", please?

            I was a bit unclear. When you write a component (i.e. a qml file which can be used from other qml files) you've got the top level item first. For that item you can give implicitWidth/Height if there are reasonable default values for the size of that component. But you shouldn't give width/height properties explicitly.

            //MyItem.qml
            import QtQuick...//whatever you need to import
            Item{ // top level item, rectangle, button or whatever
                id: control
                //width: 100 No!
                implicitWidth: 100 // Yes
                Rectangle{ // inner items go here
            }
            

            When you use that component in another file you can there give w/h explicitly.

            //main.qml
            ...
            MyItem {
                width: 150 //yes
            }
            

            In many situations it doesn't matter whether you give explicit or implicit size and where you give it. In some situations it matters. It's better to use implicit in components themselves and explicit when you instantiate a component. However, look at what is done in the Material theme's Button.qml in Components 2:

            T.Button {
                id: control
                implicitWidth: Math.max(background ? background.implicitWidth : 0,
                                        contentItem.implicitWidth + leftPadding + rightPadding)
                implicitHeight: Math.max(background ? background.implicitHeight : 0,
                                         contentItem.implicitHeight + topPadding + bottomPadding)
            ...
            contentItem: Text {
            ...
            }
            background: Rectangle {
                    implicitWidth: 64
                    implicitHeight: 48
                    ...
                    width: parent.width
                    height: parent.height - 12
                    ...
            }
            ...
            }
            

            The background rectangle has both implicit and explicit size! The control itself has only implicit size which is max of background's implicit size and contentItem's implicit size (which is the text's size by default). When you instantiate the Button and don't give explicit size the implicit size is used. The engine gives the actual width and height values based on implicit size. The background will get the same size which by default will be the same as control's implicit size. If, on the other hand, the developer gives explicit size (width&height) when the Button is instantiated, implicit size of the control is bypassed and both the component itself and the background will get that explicit size. The Text element will be elided if the explicit width is smaller than text's implicit width.

            1 Reply Last reply
            0
            • tomyT tomy

              @Eeli-K
              Thank you.

              you shouldn't explicitly give the top level item's height & width.

              Did you mean "the top level item height & width", please?

              IDs are necessary only if the object must be known by name somewhere, but it may still be good for self-documentation. Come up with a descriptive name for an object and you may thank yourself later when you read your own code because you will know without further thinking why you have made the object.

              Yes, you're right. Thanks.

              import QtQuick.Controls 2.0
              

              means that Controls 2 are used, not Controls 1. Change it to

              import QtQuick.Controls 1.4
              

              What does it mean please, I can't understand well. Isn't Controls 2 used? Where is it stated?

              // property names must always begin with lower case, Text is a type name!

              Good info.
              And when I use that style for the buttons, they won't be appeared on output!

              E Offline
              E Offline
              Eeli K
              wrote on last edited by
              #10

              @tomy

              What does it mean please, I can't understand well. Isn't Controls 2 used? Where is it stated?

              There are two sets of UI controls in Qt Quick, Controls 1 and Controls 2. Usually only one of them is selected for a given application, although they can be used together. Under the hood they work differently and they have different look&feel. You must import the one you are using (or both if you are using both in the same component). In Qt 5.9 the version of Controls 1 is 1.4 and the version of Controls 2 is 2.2. You can import an older version (at least for Controls 2), too, if you don't use features which require a newer version.

              I used Button from Controls 2. Both Controls 2 and Controls 1 have a type named Button which both have a property named text. Therefore a simple button works if you change the import statement from version 1.4 to 2.2 or vice versa. However, only Controls 1 use the 'style' property for styling. Therefore it didn't work when only Controls 2 was imported.

              1 Reply Last reply
              1
              • tomyT Offline
                tomyT Offline
                tomy
                wrote on last edited by
                #11

                Thank you.
                Here is main.qml and styles don't work yet! That is, when I use them this way no button will be shown on output.

                import QtQuick 2.8
                import QtQuick.Window 2.2
                import QtQuick.Controls 1.4
                import QtQuick.Controls.Styles 1.4
                
                Window {
                    visible: true
                    width: 700
                    height: 600
                    title: qsTr("Transformation")
                
                    Column {
                         spacing: 10
                
                     Transformation {
                             id: transformation
                           }
                
                    Button {
                         id: t_o_button
                         text: "test_overlap"
                         style: ButtonStyle
                         onClicked: transformation._test_overlap()
                          }
                
                     Button {
                         id: t_t_button
                         text: "test_transformed"
                         style: ButtonStyle
                         onClicked: transformation._test_transformed()
                      }
                
                     Button {
                         id: quit_button
                         text: "Quit"
                         style: ButtonStyle
                         onClicked: close()
                     }
                   }
                }
                

                In programs, for example like this, how should use the components in main.qml? It seems that every component has the instances of another component in itself and we instantiate the most top component, on a hierarchy when each has instances of the the lower one. Right?

                E 1 Reply Last reply
                0
                • tomyT tomy

                  Thank you.
                  Here is main.qml and styles don't work yet! That is, when I use them this way no button will be shown on output.

                  import QtQuick 2.8
                  import QtQuick.Window 2.2
                  import QtQuick.Controls 1.4
                  import QtQuick.Controls.Styles 1.4
                  
                  Window {
                      visible: true
                      width: 700
                      height: 600
                      title: qsTr("Transformation")
                  
                      Column {
                           spacing: 10
                  
                       Transformation {
                               id: transformation
                             }
                  
                      Button {
                           id: t_o_button
                           text: "test_overlap"
                           style: ButtonStyle
                           onClicked: transformation._test_overlap()
                            }
                  
                       Button {
                           id: t_t_button
                           text: "test_transformed"
                           style: ButtonStyle
                           onClicked: transformation._test_transformed()
                        }
                  
                       Button {
                           id: quit_button
                           text: "Quit"
                           style: ButtonStyle
                           onClicked: close()
                       }
                     }
                  }
                  

                  In programs, for example like this, how should use the components in main.qml? It seems that every component has the instances of another component in itself and we instantiate the most top component, on a hierarchy when each has instances of the the lower one. Right?

                  E Offline
                  E Offline
                  Eeli K
                  wrote on last edited by
                  #12

                  @tomy About Controls1 styles: http://doc.qt.io/qt-5/qtquick-usecase-styling.html
                  About using components: http://doc.qt.io/qt-5/qtqml-syntax-basics.html

                  tomyT 1 Reply Last reply
                  1
                  • E Eeli K

                    @tomy About Controls1 styles: http://doc.qt.io/qt-5/qtquick-usecase-styling.html
                    About using components: http://doc.qt.io/qt-5/qtqml-syntax-basics.html

                    tomyT Offline
                    tomyT Offline
                    tomy
                    wrote on last edited by tomy
                    #13

                    @Eeli-K

                    About Controls1 styles: http://doc.qt.io/qt-5/qtquick-usecase-styling.html

                    Thank you, done.

                    About using components: http://doc.qt.io/qt-5/qtqml-syntax-basics.html

                    Thanks it was useful. But not exactly spotting what I meant!
                    I didn't mean parent-child relationship.

                    Look please, the program, when run, starts from somewhere and meets main.qml, ClickableImage.qml and Transformation.qml. The the output will be shown.
                    I meant, where in the components above firstly the program is started, then where it goes and where again until it finishes and shows the result on output.

                    E 1 Reply Last reply
                    0
                    • tomyT tomy

                      @Eeli-K

                      About Controls1 styles: http://doc.qt.io/qt-5/qtquick-usecase-styling.html

                      Thank you, done.

                      About using components: http://doc.qt.io/qt-5/qtqml-syntax-basics.html

                      Thanks it was useful. But not exactly spotting what I meant!
                      I didn't mean parent-child relationship.

                      Look please, the program, when run, starts from somewhere and meets main.qml, ClickableImage.qml and Transformation.qml. The the output will be shown.
                      I meant, where in the components above firstly the program is started, then where it goes and where again until it finishes and shows the result on output.

                      E Offline
                      E Offline
                      Eeli K
                      wrote on last edited by
                      #14

                      @tomy Maybe I now understand your question. Do you want to know how the objects and the object structure is created? In C++, javascript and many other languages there's a clear order of things which you can follow by reading the code. It starts with main.cpp and you can continue from there, read the code and tell what happens. But QML is declarative in nature. It means that in the code you tell what you want to get but how it's actually done is up to the QML engine. There's no predetermined initialization order which you can rely on. The code means for example:

                      "I want to get a structure of visual items where there's a top level window which has this and this control elements inside it in these visual places. The color of this one will change according to the state of that one. When this button is pressed such and such should happen." There are several possible ways how this can be achieved and you don't need to know it. The engine could for example read the code and go through the object structure several times and do different initialization steps each time. What you can rely on is that after the UI is rendered and it starts listening to user interactions everything is initialized according to the intentions you expressed in the code.

                      Logically and in practice initialization must begin somewhere; the starting point is usually main.qml but you give the name in (usually) main.cpp to the engine. The object tree will have the topmost object in main.qml as the root. In your main.qml the engine instantiates Window, inside it a Column, inside that a Transformation and Buttons. When it instantiates Transformation it must of course instantiate Item, Image and MouseArea which are inside that Transformation, and so on. But in which order everything actually is initialized and when everything is ready is up to the engine.

                      Did that answer your question or did you have something else in mind?

                      tomyT 1 Reply Last reply
                      1
                      • E Eeli K

                        @tomy Maybe I now understand your question. Do you want to know how the objects and the object structure is created? In C++, javascript and many other languages there's a clear order of things which you can follow by reading the code. It starts with main.cpp and you can continue from there, read the code and tell what happens. But QML is declarative in nature. It means that in the code you tell what you want to get but how it's actually done is up to the QML engine. There's no predetermined initialization order which you can rely on. The code means for example:

                        "I want to get a structure of visual items where there's a top level window which has this and this control elements inside it in these visual places. The color of this one will change according to the state of that one. When this button is pressed such and such should happen." There are several possible ways how this can be achieved and you don't need to know it. The engine could for example read the code and go through the object structure several times and do different initialization steps each time. What you can rely on is that after the UI is rendered and it starts listening to user interactions everything is initialized according to the intentions you expressed in the code.

                        Logically and in practice initialization must begin somewhere; the starting point is usually main.qml but you give the name in (usually) main.cpp to the engine. The object tree will have the topmost object in main.qml as the root. In your main.qml the engine instantiates Window, inside it a Column, inside that a Transformation and Buttons. When it instantiates Transformation it must of course instantiate Item, Image and MouseArea which are inside that Transformation, and so on. But in which order everything actually is initialized and when everything is ready is up to the engine.

                        Did that answer your question or did you have something else in mind?

                        tomyT Offline
                        tomyT Offline
                        tomy
                        wrote on last edited by tomy
                        #15

                        @Eeli-K

                        Did that answer your question or did you have something else in mind?

                        It did, yes. I understood the initialisation and it's logical because when no, say, button is clicked why initialising it!

                        For completing my understanding please also take a look at this:

                        When I run that program, it firstly goes to main.cpp and loads main.qml from there.
                        In main.qml we have a window, it will be set and an instance of Transformation which is created by:

                        Transformation {
                                    id: transformation
                                  }
                        

                        (the id: transformation is not even mandatory for having an instance of the component Transformation, I suppose)

                        When we created an instance this way, then the engine/system/even loop (whatever), goes to the definition/declaration of that component (Transformation).

                        It sees that it has an Item as root, an Image, a MouseArea and a few ClickableImage "instances", so it therefore goes to the ClickableImage component (ClickableImage.qml) and sees an Image and MouseArea there too.

                        After these the engine/system gets back to the main.qml and puts whatever Transformation component has on the screen followed by the three buttons declared below.

                        Not very wrong?

                        E 1 Reply Last reply
                        0
                        • tomyT tomy

                          @Eeli-K

                          Did that answer your question or did you have something else in mind?

                          It did, yes. I understood the initialisation and it's logical because when no, say, button is clicked why initialising it!

                          For completing my understanding please also take a look at this:

                          When I run that program, it firstly goes to main.cpp and loads main.qml from there.
                          In main.qml we have a window, it will be set and an instance of Transformation which is created by:

                          Transformation {
                                      id: transformation
                                    }
                          

                          (the id: transformation is not even mandatory for having an instance of the component Transformation, I suppose)

                          When we created an instance this way, then the engine/system/even loop (whatever), goes to the definition/declaration of that component (Transformation).

                          It sees that it has an Item as root, an Image, a MouseArea and a few ClickableImage "instances", so it therefore goes to the ClickableImage component (ClickableImage.qml) and sees an Image and MouseArea there too.

                          After these the engine/system gets back to the main.qml and puts whatever Transformation component has on the screen followed by the three buttons declared below.

                          Not very wrong?

                          E Offline
                          E Offline
                          Eeli K
                          wrote on last edited by
                          #16

                          @tomy

                          I understood the initialisation and it's logical because when no, say, button is clicked why initialising it!
                          By "initialization" I mean the phase before the object tree is fully constructed so that all objects which are reached by the declared tree are ready and all properties have expected values. So a button is initialized even if it's never clicked.

                          Otherwise what you said is a logical way to see it. However, we must keep in mind that this may still be different from the actual execution order of initialization. For example it's undermined in which order a structure like

                          Item{
                              //properties...
                              Rectangle{
                                  //properties...
                                  Rectangle{}
                              }
                              Button{
                                  //properties...
                              }
                          }
                          

                          is actually initialized: whether Item's all properties will be ready before the outer Rectangle's or whether the Button is ready before the Rectangles. The idea of the declarative nature of QML is that you don't need to know.

                          1 Reply Last reply
                          1
                          • tomyT Offline
                            tomyT Offline
                            tomy
                            wrote on last edited by
                            #17

                            Thank you. I think I got all that was needed.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved