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

Reply via email to