Dear Dirk, Sebastian,

If it were possible to have feedback from you based on not more than 15 minutes of your time, I would greatly appreciate it. I am trying to get the QML to signal to the C++ and, due to newby inexperience, I am totally stuck. I address a number of issues here, but the first one is the substantive one, the others are small. I take the liberty of attaching the code in three files.

1) Signalling from the Continue button in the QML to the appropriate C++ slot. I use an approach as close as possible to that of QmlManager in Subsurface-mobile. I create a message object with a slot, and connect this to the QML signal. Using QtCreator I get a compile-time error: /home/willem/qml/vendor/main.cpp:48: error: undefined reference to `GUIMessageClass::~GUIMessageClass()' There is a possibility this is a systemic problem related to the way of presenting code to QTCreator, but I am too naïve to be able to determine this. Any comment at all will be invaluable.

2) In the object in the header file, what does ~MessageClass mean? It eliminates a compilation error for this code.

3) With respect to the two models used in the QML, I get warnings from the QML debugger in QtCreator:

qrc:main.qml:24: ReferenceError: vendorModel is not defined

qrc:main.qml:35: ReferenceError: productModel is not defined

qrc:main.qml:35: ReferenceError: productModel is not defined

These warnings do not cause faulty execution, though. But I would love to know how they arise.

4) When running the code within QtCreator, the combo boxes do not work well. They need to be clicked several times before the options are shown. However, if I provide models inside of QML (i.e. not using a C++ external source) and I run the code using qmlscene, then the combo boxes work as expected. So, FOR THE MOMENT I assume it is a problem in the way QtCreator does the QML interpretation and that the QML is likely to run as expected on a mobile device.
Kind regards,
willem

#include <QGuiApplication>
#include <QQmlProperty>
#include <QStringList>
#include <QStringListModel>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QQmlApplicationEngine>
#include <QObject>
#include <QString>
#include "main.h"

/*  // These are the contents of the main.h header file:
class GUIMessageClass : public QObject
{   // Create a custom class to create a slot to receive messaging from QML to C++
    Q_OBJECT
    Q_PROPERTY(QString msgText READ msgText WRITE setMsgText NOTIFY msgTextChanged)

    public:
        GUIMessageClass();
        ~GUIMessageClass();

        static GUIMessageClass *instance();

        QString msgText() const;
        void setMsgText(const QString &msgText);

    public slots:
        void msgSlot(const QString &msgText) {
            qDebug() << "C++ received QML signal with message:" << msgText;
        }

    signals:
        void msgTextChanged();
};
*/

int main(int argc, char ** argv)
{
    QVariant s1;
    QGuiApplication app(argc, argv);

    QQuickView view;
    view.setSource(QUrl("qrc:main.qml"));
    QObject *dcSelectPanel = view.rootObject();  // Get pointer to QML GUI
/*
    GUIMessageClass MessageClass;
                            // Connect the GUI to the MessageClass object:
    QObject::connect(dcSelectPanel,
                     SIGNAL(selectionDoneSignal(QString)),
                     &MessageClass,
                     SLOT(msgSlot(QString)));
*/
    QStringList vendorList;
    vendorList.append("Suunto");
    vendorList.append("Mares");
    vendorList.append("Scubapro");
    vendorList.append("Cressi");

    QStringList productList;
    productList.append("Aladin");
    productList.append("Meridian");
    productList.append("Galileo");
    productList.append("Smart");

    QQmlContext *ctxt = view.rootContext();
    ctxt->setContextProperty("vendorModel", QVariant::fromValue(vendorList));
    ctxt->setContextProperty("productModel", QVariant::fromValue(productList));

    view.show();

    //  Get QML combobox data : (This appears to work)
    //  ==============================================
/*
    QObject *vBox = dcSelectPanel->findChild<QObject*>("vendorBox");  // This approach appears to work
    if (vBox) qDebug() << "vBox 1 found\n"; else qDebug() << "vBox NOT found\n";

    QQmlEngine engine;                                              // and this different approach too.
    QQmlComponent mainWindow(&engine, "/home/willem/qml/vendor/main.qml");
    QObject *object = mainWindow.create();

    QObject *vBox2 = object->findChild<QObject*>("vendorBox");      // get pointer to comboBox
    if (vBox2) qDebug() << "vBox 2 found\n"; else qDebug() << "vBox2 NOT found\n";

    int i = vBox2->property("currentIndex").toInt();                // Read currentIndex
    qDebug() << "vBox2 index=" << i;

    QString s = vBox2->property("textAt(currentIndex)").toString(); // Read currentText
    qDebug() << "vBox2 text=" << s; */


    return app.exec();
}


#include "main.moc"
class GUIMessageClass : public QObject
{   // Create a custom class to create a slot to receive messaging from QML to C++
    Q_OBJECT
    Q_PROPERTY(QString msgText READ msgText WRITE setMsgText NOTIFY msgTextChanged)

    public:
        GUIMessageClass();
        ~GUIMessageClass();

        static GUIMessageClass *instance();

        QString msgText() const;
        void setMsgText(const QString &msgText);

    public slots:
        void msgSlot(const QString &msgText) {
            qDebug() << "C++ received QML signal with message:" << msgText;
        }

    signals:
        void msgTextChanged();
};
import QtQuick 2.2
import QtQuick.Controls 1.1

Rectangle {
    width: 400; height: 250
    id: dcSelectPanel
    objectName: "dcSelectPanel"

    signal selectionDoneSignal(string buttontext)
/*
    ListView {
        width: 100; height: 100; model: vendorModel
        delegate: Rectangle { height: 20; width: 100
            Text { text: modelData }
    }   }
*/
    Text { x:5; y: 10; text: "Select dive computer" }

    Text { x: 5; y: 50; text: "Vendor" }
    ComboBox {                     // Combobox listing the vendors
        x: 5;  y: 70; width: 150
        id: vendorBox
        objectName: "vendorBox"
        model: vendorModel
        onCurrentIndexChanged: {
            console.log("Vendor: " + currentIndex +  " " + currentText)
        }
    }

    Text { x: 200; y: 50; text: "Product" }
    ComboBox {                    // Combobox listing all the equipment for a specific vendor
        x: 200; y: 70; width: 150
        id: productBox
        objectName: "productBox"
        model: productModel
        onCurrentIndexChanged: {
            console.log("Equipment: " + currentIndex +  " " + currentText)
        }
    }

    Button {
        id: signalButton
        objectName: "signalButton"
        signal buttonSignal(string msg1)
        x:5; y: 180; width: 100; height: 20; text: "Continue"
        onClicked: {
            dcSelectPanel.selectionDoneSignal("Button-signal")
        }
    }

}   // Rectangle
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to