user6283344
user6283344

Reputation:

Populate ComboBox from QList<QObject*>

I was following an example on web to populate combobox, but it did not wok for me and I do not know why!. I have two classes stock and DbCon, stock has three private fields along with public accessor and mutators. DbCon has a Q_Property and two public function, one returns a database connection and the other creates and returns stock list as a QList<QObject*>. In main.cpp I have created a contextual property named "data" to access DbCon from QML.

in main.qml I have

....
ComboBox{
        model: data.stockModel
        textRole: "code"
 }
....  

in main.cpp

DbCon db;
engine.rootContext()->setContextProperty("data", &db);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

in dbcon.h

class DbCon:public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QObject*> stockModel READ stockModel)

public:
    explicit DbCon(QObject *parent = 0);
    QSqlDatabase db();
    QList<QObject*> stockModel();
};

in implementation of QList<QObject*> stockModel() of dbcon.h

QList<QObject*> data;
....
while (query.next()) {
    stock *s = new stock();
    ....
    data.append(s);
}
return data;

and in stock.h

class stock : public QObject
{
    Q_OBJECT
private:
    QString m_name;
    QString m_code;
    int m_id;

public:
    explicit stock(QObject *parent = 0);
    QString name();
    void setname(QString &name);
    QString code();
    void setcode(QString &code);
    int id();
    void setid(int &id);
};

When I run the application I get the following message in application output

QQmlExpression: Expression qrc:/main.qml:16:20 depends on non-NOTIFYable properties: QQuickComboBox::data

and I do not get anything in combobox!

If I create another contextual property in main.cpp in this way

engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(data));

and set myModel as model for combobox, it works fine. But I want to do it in this way because onCurrentIndexChanged I will call another function that returns another QList<QObject*> for a TableView of another qml file.


EDIT: Entrie qml

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
    visible: true
    width:600
    height:600
    property string contentSource

    Column{
        spacing:10
        ComboBox{
            model: data.stockModel
            textRole: "code"
        }
        Loader {
            id: content
            width: parent.width
            height:400
        }
        Row{
            spacing:10
            Button{
                text: "Page1"
                onClicked: content.source = "Page1.qml"
            }
            Button{
                text: "Page2"
                onClicked: content.source = "Page2.qml"
            }
        }
    }
}

By changing data to dataStore in main.cpp and data.stockModel to dataStore.stockModel in main.qml I get following error

file:///C:/Qt/Qt5.7.0/5.7/mingw53_32/qml/QtQuick/Controls.2/ComboBox.qml:62:15: Unable to assign [undefined] to QString

Upvotes: 0

Views: 3753

Answers (1)

E4z9
E4z9

Reputation: 1767

You have two issues:

  1. Your stockModel property should be NOTIFYable, which means that you should define the property with e.g. Q_PROPERTY(QList<QObject*> stockModel READ stockModel NOTIFY stockModelChanged) and provide a void stockModelChanged(const QList<QObject *> &) signal in the DbCon class.
  2. stock::name() must be a property too, so you need to declare that with Q_PROPERTY(QString name READ name NOTIFY nameChanged) and provide a void nameChanged(const QString &) signal in the stock class as well.

Upvotes: 0

Related Questions