Using components for the first time



  • Hello,

    I'm new in QML. I read an online book and am dealing with this section right now.
    I don't know it's me that is so new in QML that don't figure the whole matter out completely or the book isn't written well for beginners.

    I created a Qt Quick Application project and named it Rec. (Qt 5.9)
    These are my files:

    main.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    main.qml:

    import QtQuick 2.6
    import QtQuick.Window 2.2
    
    Window {
        id: root
        visible: true
        width: 640
        height: 480
        title: qsTr("Rec")
    
       Button {
           id: button
           x: 12; y: 12
           text: "Start"
           onClicked: {
               status.text = "Button clicked!"
           }
       }
    
       Text {
           id: status
           x: 12; y: 76
           width: 116; height: 26
           text: "waiting ..."
           horizontalAlignment: Text.AlignHCenter
       }
    
       Rectangle {
          x: 50; y: 10
          width: 120; height: 240
          color: "purple"
          radius: 12
          MouseArea {
              id: area
              width: parent.width
              height: parent.height
              onClicked: {
                  rec.visible = !rec.visible
                  tri.visible = !tri.visible }
             }
          }
    
          Rectangle {
              id: rec
              x: 250; y: 25
              width: 140; height: 80
              border.color: "lightsteelblue"
              border.width: 5
              radius: 25
    
          }
    
          Image {
              id: tri
              x: 200; y: 150
              source: "/triangle_red.png"
              fillMode: Image.PreserveAspectCrop
              clip: true
           }
    
           Text {
               x: 280; y:50
               width: 40
               height: 120
               text: 'A very long text'
               elide: Text.ElideMiddle
               style: Text.Sunken
               styleColor: '#FF4444'
               verticalAlignment: Text.AlignTop
           }
     }
    

    button.qml:

    // minimal API for a button
    import QtQuick 2.5
    
    Rectangle {
        id: root
        Button {
          text: "Click Me"
          onClicked: { /* do something*/ }
         }
    
        property alias text: label.text
        signal clicked
    
        width: 116; height: 26
        color: "lightsteelblue"
        border.color: "slategrey"
    
        Text {
            id: label
            anchors.centerIn: parent
            text: "Start"
        }
    
        MouseArea {
            anchors.fill: parent
            onCanceled: {
                root.clicked()
            }
        }
    }
    

    I also have a .png file in Resources.
    Before this section the project ran well. I created that button.qml and filled it out. Now I get an error:
    \Rec\build-Rec-Desktop_Qt_5_9_0_MinGW_32bit-Debug\debug\Rec.exe exited with code -1

    The "Button" in underlined with a red line.
    What should I have done, please?


  • Moderators

    File Button.qml should start with a capital letter. Only such files are recognized by QML engine as Components.



  • @sierdzio
    Where should I make the first letter capital?
    I added this file to Resources by:
    Add New -> C++ source file -> Button.qml -> OK
    But in the Qt Creator it turned out to button.qml.
    I think no file in Qt creator is shown with a capital letter.


  • Moderators

    Hm, weird. But in your filesystem, the Button.qml starts with a capital letter, right?

    Open your QRC file in text editor and see if the name starts in upper case, too. Actually, maybe paste the QRC file here if you can, we'll see if it looks OK. QML engine should automatically pick it up if it is in the same folder as main.qml. But if the folder is different, you will need to import it.



  • I've been working a little on Qt and seen the files in the Project view on the Qt creator. I have seen no file with a capital letter so far.

    Here is an image. What else is need I will post. Thanks.

    0_1504776411688_Capture.PNG


  • Moderators

    Ah, Windows and it's case insensitiveness :-)

    Anyway, I see Qt Creator does recognize Rec with capital R, so it should also recognize the button. Rename it to Button.qml please (right click on button.qml and select rename). If it still does not work, open the QRC in text editor (right click -> open with -> plain text editor) and verify that it is capital letter.



  • The file is Buttun now, but the prior error still exits.
    Did you think I'm using Linux?


  • Moderators

    @tomy said in Using components for the first time:

    The file is Buttun now, but the prior error still exits.

    Do a full rebuild (clean, run qmake, rebuild). Perhaps the build system is not picking up the name change.

    Did you think I'm using Linux?

    No, I was not thinking about OS at all, to be honest :-)



  • OK, and thank you. But I should make you aware that although I did the three but still that error!
    In the main.cpp we have this:

    if (engine.rootObjects().isEmpty())
            return -1;
    

    Isn't it because of that? Because the error says: "Rec.exe exited with code -1".


  • Moderators

    @tomy said in Using components for the first time:

    OK, and thank you. But I should make you aware that although I did the three but still that error!
    In the main.cpp we have this:

    if (engine.rootObjects().isEmpty())
            return -1;
    

    Isn't it because of that? Because the error says: "Rec.exe exited with code -1".

    That is the result of error, not the cause. Engine's rootObjects are empty when there is an error in parsing / loading the QML code. In that case, the app will exit with -1 (and thus the operating system knows it was not a clean exit, but some error happened).

    So, that code is good. Without it, the application would continue to run, but display an empty window. You can try commenting these 2 lines out to see that.

    But I should make you aware that although I did the three but still that error!

    Ah, silly me! I've got so focused on the naming issue that I have not checked your Button.qml code. It has an error (btw. Qt Creator should print QML errors for you): you use Button component inside Button.qml (in other words, Button tries to create Button inside, which tries to create Button inside etc.). There are several ways out of this problem:

    • import QtQuick.Controls 2.0 in Button.qml, so the QML engine will use the built-in Button element inside your custom button
    • remove Button from Button.qml, replace it with (for example) Text + MouseArea


  • Thanks.

    I used Button.qml this way: (as that section says)

    // minimal API for a button
    import QtQuick 2.5
    
    Item {
        id: root
        property alias text: label.text
        signal clicked
    
       Rectangle {
           id: rect
        anchors.centerIn: parent
        color: "lightsteelblue"
        border.color: "slategrey"
      }
       Text {
            id: label
            anchors.centerIn: parent
            text: "Start"
        }
    
        MouseArea {
            anchors.fill: parent
            onClicked: root.clicked()
        }
    }
    

    And main.qml:

    import QtQuick 2.6
    import QtQuick.Window 2.2
    
    Window {
        id: root
        visible: true
        width: 640
        height: 480
        title: qsTr("Rec")
    
       Button {
           x: 450; y: 50
           text: "First"
           onClicked: status.text = "First Button clicked!"
       }
    
       Button {
           x: 450; y: 100
           text: "Second"
           onClicked: status.text = "Second Button clicked!"
       }
    
       Button {
           x: 450; y: 150
           text: "Quit"
           onClicked: close();
       }
    
       Text {  // text changes when button was clicked
           id: status
           x: 450; y: 76
           width: 116; height: 26
           text: "waiting ..."
           horizontalAlignment: Text.AlignHCenter
       }
    }
    

    When I run the program and click on either First, Second or Quit button, nothing happens. Why please?
    And what is the usage of that Rectangle in Button.qml, please?

    0_1504944725270_Capture.PNG



  • @tomy I suggest avoiding existing Qt QML/Quick/Components type names to avoid possible problems. "Button" is already a type name in Components 1 and 2. Use MyButton.qml or something more descriptive. It may not matter here but can save you from some confusions and problems later.

    This fixes your problem:

    // minimal API for a button
    import QtQuick 2.5
    
    Item {
        id: root
        property alias text: label.text
        signal clicked
        implicitHeight: 50
        implicitWidth: 100
        Rectangle {
            id: rect
            anchors.fill:parent
            color: "lightsteelblue"
            border.color: "slategrey"
        }
        Text {
            id: label
            anchors.centerIn: parent
            text: "Start"
        }
    
        MouseArea {
            anchors.fill: parent
            onClicked: root.clicked()
        }
    }
    

    The rectangle is just a backround so that you can define a color for your button. Item has only size and position but no visible appearance. I made the rectangle to fill the parent item. I also added size to your button. Otherwise you should set the height/width for them in your main.qml. In your version the button (i.e. the 'root' item) didn't have any size. Only the text inside the button had size but the item itself and the mouse area inside it were of size 0 x 0.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.