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 -1The "Button" in underlined with a red line.
What should I have done, please? -
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. -
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.
-
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.
-
@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 :-)
-
-
@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? -
@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.