1
votes

I have two combo boxes, the data for the second one being determined by that of the first one. The number of strings in the second combo box varies from 2 to 4. If I:

  1. select a new string in the first combo box and
  2. the last choice is selected in the second combo box with a longer list than the previous list of that box,

the currentString in the second combo box remains and overrides the correct text

For instance, if I select Scubapro in the first combo box (4 options in 2nd box) and Smart in the second combo box (the 4th option), then select any other choice in the first combo box again (< 4 options in 2nd box), the entry in the second combo box remains "Smart", which is inappropriate. The correct list is, however, loaded into the 2nd combo box. Inspection of the underlying stringlist also suggests that it contains the correct data. The problem appears to be the visual updating of the second combo box. The heart of the algorithm comes from Stackoverflow and is the generator called each time text in combo box 1 changes. What can one do to rectify this?

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQuickView>
#include <QQuickItem>
#include <QStringListModel>
#include <QQmlContext>
#include <QDebug>

QStringList dat1, dat2, dat3;
QStringList vendorList;

class Generator : public QObject

    Q_OBJECT
    QStringListModel * m_model;
public:
    Generator(QStringListModel * model) : m_model(model) {}
    Q_INVOKABLE void generate(const QVariant & val) {

        m_model->removeRows(0,m_model->rowCount()); // This has no effect

        if (QString::compare(val.toString(),   QString::fromStdString("Mares"), Qt::CaseInsensitive) == 0) {
            m_model->setStringList(dat1);
        }
        else {
            if (QString::compare(val.toString(),     QString::fromStdString("ScubaPro"), Qt::CaseInsensitive) == 0) {
                m_model->setStringList(dat2);
            }
            else
                m_model->setStringList(dat3);
        }

};


int main(int argc, char *argv[])
{
    QStringListModel model1, model2;
    generator(&model2);

    dat1 << "Puck" << "Nemo" << "Matrix";
    dat2 << "Aladin" << "Meridian" << "Galilio" << "Smart";
    dat3 << "D4" << "D6";
    vendorList << "Mares" << "Scubapro" << "Suunto" << "Shearwater";
    model1.setStringList(vendorList);

    QGuiApplication app(argc, argv);
    QQuickView view;

    QQmlContext *ctxt = view.rootContext(); 
    ctxt->setContextProperty("model1", &model1);
    ctxt->setContextProperty("model2", &model2);
    ctxt->setContextProperty("generator", &generator);

    view.setSource(QUrl("qrc:main.qml"));
    view.show();

    return app.exec();
}

#include "main.moc"

Here is the QML:

import QtQuick 2.0
import QtQuick.Controls 1.0

Rectangle {
width: 400; height: 300
    Text { text: "Vendor";  }
    Text {
        x: 200
        text: "Product"; }
    ComboBox {
        id: box2
        objectName: "productBox"
        x:200; y:25; width: 180
        model: model2
        textRole: "display"
    }

    ComboBox {
        y:25; width: 180
        id: box1
        model: model1
        textRole: "display"
        onCurrentTextChanged:  {
            generator.generate(currentText)
        }
    }

}

Any comments are highly appreciated.

1

1 Answers

0
votes

The ComboBox item does not react to changes performed under the hood to the model.

There are a couple of solutions to work around it.

A possible one is to reassign the model to itself at the end of the signal handler, by using the statement:

model = model;

As from the documentation:

Changing the model after initialization will reset currentIndex to 0.

Otherwise, you can explicitly set currentIndex to your preferred value or, even better, to -1.
In fact, from the documentation we have that:

Setting currentIndex to -1 will reset the selection and clear the text label.