I am starting to gear up to make a contribution to part of the QML UI of
Subsurface-mobile. This is my first exposure to Qt and QML, and the
learning curve is pretty steep, augmented by the fact that I cannot find
a comprehensive reference manual. For instance when trying to find out
what the textRole of a QML element should contain there is only cursory
mentions of this in the documentation that I looked at and nothing that
is worth using.
Attached are three files on which I would really appreciate comment, two
QML and one C++. Please look at the C++ file first, then look at
view.qml. Basically I take a StringList and pass it from C++ to QML.
Then I display the stringlist as elements of a list view and also in a
ComboBox in QML. Lastly I attempt to send a signal from QML directed at
a slot in the C++ code and, within C++, print out the message associated
with the signal from QML. I made extensive comments and discussion in
the code. If anyone is prepared to comment or give advice I would
appreciate it immensely.
Kind regards,
willem
#include <QGuiApplication>
#include <QStringList> // Objectives of this code:
// 1) Create a QStringlist and expose it to QML.
#include <qqmlcontext.h> // 2) Execute the QML
#include <qqml.h> // 3) Listen for a signal from the QML button and print it to console (qDebug)
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QStringListModel>
#include <QQmlApplicationEngine>
class MessageClass : public QObject { // Create a custom class to create a slot to receive messaging from QML to C++
Q_OBJECT
public slots: // I get compilation error: "undefined reference to vtable for MessageClass" Huh??
void ButtonSlot(const QString &msg1) { // Is this the most efficient way to do this?
qDebug() << "C++ called by:" << msg1;
}
};
int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
QStringListModel vendorModel; // Create a QStringList to hold names of dive computers
QStringList dataList;
dataList.append("Suunto");
dataList.append("Mares");
dataList.append("Scubapro");
dataList.append("Cressi");
// I create a model, but do not use it.
vendorModel.setStringList(dataList); // The setContextProperty below uses the QStringList, not the model.
// What is the most efficient way to expose the QStringList as a QML model?
QQuickView view;
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("vendorModel", QVariant::fromValue(dataList));
view.setSource(QUrl("qrc:view.qml"));
// Signalbutton is supposed to point to signalButton in the QML.
QObject *signalButton = view.rootObject(); // I doubt whether this is the right way to do it.
// I would appreciate comment on this point.
MessageClass ButtonMessage;
QObject::connect(signalButton, SIGNAL(buttonSignal(QString)),
&ButtonMessage, SLOT(ButtonSlot(QString)));
// This is supposed to connect the QML signal to the C++ slot.
view.show();
return app.exec();
}
import QtQuick 2.0
import QtQuick.Controls 1.0
Rectangle {
width: 300; height: 300
Item { width: 5; height: 5 }
ListView {
width: 100; height: 100 // This executes correctly, shows
QStringList.
model: vendorModel // I conclude that the QML can
correctly see
delegate: Rectangle { // the C++ QStringList and that this
part is
height: 20 // done correctly in C++.
width: 100
Text { text: modelData }
}
} // ListView
Text { x: 5; y: 100; text: "Vendor" }
ComboBox {
x: 5; y: 120 // This does NOT show the same
QStringList above
id: vendorBox // It sees four items that are empty.
model: vendorModel // I suspect the textRole is specified
incorrectly.
textRole: "modelData" // I cannot find any documentation on
what exactly QtQuick
// textRole: "display" // roles are and how they should be
specified. :-( If I have a
} // QStringList with named fields, and I
use the name of a named field,
// then the data are shown correctly.
(See tst.qml, attached)).
Button {
id: signalButton
signal buttonSignal(string msg1)
x:20; y: 200; width: 100; height: 20; text: "Send signal"
onClicked: {
buttonSignal("Button-signal") // By hitting this button, a signal
should be sent to C++
// that, in turn, prints the
message on the console/terminal.
} // Eventually I want to use this
with the OnIndexChanged
} // property of the Combobox, above.
// I have no evidence that the
present code is correct.
} // Rectangle
import QtQuick 2.3
import QtQuick.Controls 1.4
Rectangle {
width: 200; height: 100; color: "#cccccc"
ListModel {
id: dc_NameModel
ListElement { dcname: "Suunto"; d_use: "tec" }
ListElement { dcname: "Mares" ; d_use: "tec" }
ListElement { dcname: "Scubapro"; d_use: "OW" }
ListElement { dcname: "Cressi"; d_use: "OW" }
ListElement { dcname: "Shearwater"; d_use: "OW" }
}
CheckBox {
x: 1; y: 45
id: chkPlatformAutoRepeat
text: ""
}
Text {
id: dcText
x: 20
y: 10
text: "Divecomputer type"
}
ComboBox { // This correctly displays the dc names
in the listmodel defined above.
id: dcMakeBox // Note the textRole value. No other
textRole value works.
x: 20; y: 30; width: 150
model: dc_NameModel
textRole: "dcname"
onCurrentIndexChanged: console.debug((dcMakeBox.currentIndex+1)+"
"+dcMakeBox.currentText)
}
Button {
x:20; y: 70; width: 80; height: 20; text: "Quit"; opacity: 0.25
onClicked: {
Qt.quit()
}
}
}
// /home/willem/Qt/5.5/gcc_64/bin/qmlscene tst.qml
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface