Setting ListView model from C++



  • Hello.
    I'm trying to add tab with ListView from C++. Creating/adding tab part is already done :D But i have trouble with creating my model and assigning it to ListView which is in created Tab.
    So far I have following code:

    main.cpp:

    	QObject* pRoot = mAppEngine->rootObjects()[0];
    	QObject* m_pTabView= pRoot->findChildren<QObject*>("conversationTabView").first();
    	if (m_pTabView)
    	{
    	QVariant returnedValue;
    	QVariant title = phoneNumber;
    	QQmlComponent *component = new QQmlComponent(mAppEngine, QUrl("qrc:/ChatView.qml"), this);
    	QObject *object = component->create();
    	QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
    	object->setProperty("active", QVariant(true));
    	component->setParent(m_pTabView);
    
    	QMetaObject::invokeMethod(m_pTabView, "addTab",
    	Q_RETURN_ARG(QVariant, returnedValue),
    	Q_ARG(QVariant, title),
    	Q_ARG(QVariant, QVariant::fromValue(component)));
    
    	object->setProperty("anchors.fill", "parent");
    
    	SmsModel *model = new SmsModel();
    	mode->createDummyData();
    
    	QObject *p = object->findChild<QObject*>("chatView");
    	if (p)
    	p->setProperty("model", QVariant::fromValue(model));
    	else
    		qDebug() << "chatView not found";
    

    and ChatView.qml

    Rectangle {
        color: "#E0E0E0"
        ListView {
            objectName: "chatView"
            id: chatView
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.bottom: messageRect.top
            clip: true
            delegate: bubbleDelegate
            Component {
                id: bubbleDelegate
                Rectangle {
                    implicitWidth: messageText.implicitWidth + 2*messageText.anchors.margins
                    implicitHeight: messageText.implicitHeight + 2*messageText.anchors.margins
                    anchors.left: model.received ? parent.left : undefined
                    anchors.right: model.received ? undefined : parent.right
                    anchors.margins: 5
                    id: bubble
                    smooth: true
                    radius: 10
                    color: model.received ? "#673AB7" : "#E040FB"
                    Text {
                        id: messageText
                        anchors.fill: parent
                        anchors.margins: 5
                        text: model.message
                        wrapMode: Text.WordWrap;
                        horizontalAlignment: model.received ? Text.AlignLeft : Text.AlignRight
                        color: "white"
                    }
                }
            }
        }
    

    But it is showin only grey form(from Rectangle). No data in ListView are present. What should I do/change in this code to have this working?

    Thank yout for every response.



  • Is your mAppEngine of class QQmlApplicationEngine? If so, and if your SmsModel class is derived from QListModel, you can assign the model for the ListView as follows:

       qmlRegisterType<SmsModel>("CustomComponents", 1, 0, "SmsModel");
       mAppEngine .rootContext()->setContextProperty("listModelName", &model);
    

    In the ListView in ChatView.qml, set:

       model: listModelName
    

    It might get a little trickier depending on when you load ChatView, though.



  • Yes. mAppEngine is instance of QQmlApplicationEngine. I would like to assign one model to one ListView(in case of many tabs created). I tried this:

        SmsModel *model = new SmsModel();
        model->createDummyData();
    	QObject* pRoot = mAppEngine->rootObjects()[0];
    	QObject* m_pTabView= pRoot->findChildren<QObject*>("conversationTabView").first();
    	if (m_pTabView)
    	{
    	QVariant returnedValue;
    	QVariant title = phoneNumber;
    	QQmlContext *context = new QQmlContext(mAppEngine, mAppEngine);
    	context->setContextProperty(QString("myModel"), model);
    	mAppEngine->rootContext()->setContextProperty("mmm", model);
    	QQmlComponent *component = new QQmlComponent(mAppEngine, QUrl("qrc:/ChatView.qml"), this);
    	QObject *object = component->create(context);
    	QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
    
    	object->setProperty("active", QVariant(true));
    	component->setParent(m_pTabView);
    
    	QMetaObject::invokeMethod(m_pTabView, "addTab",
    	Q_RETURN_ARG(QVariant, returnedValue),
    	Q_ARG(QVariant, title),
    	Q_ARG(QVariant, QVariant::fromValue(component)));
    
    	object->setProperty("anchors.fill", "parent");
    }
    

    and in QML:

    Rectangle {
    ...
      ListView {
        model: myModel
      }
    }
    

    I get this error "ReferenceError: myModel is not defined". When I do

    mAppEngine->rootContext()->setContextProperty("myModel", model);
    

    I have data in GUI, but when I create two tabs, then both ListViews share the same model(I want one model <-> one ListView).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.