Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Compare Items of listview and aray



  • Hello and good Morning.

    I hope i can get help here with my Problem.

    I have a listview which has a lot of delegates. I Need the text of all delegates in one Array so i can compare it to what is the expected Content in the list.
    I use python as a language.

    What i know:
    I Need the Children of Children in the listview because there is one Content item in between.
    But i cant make it work.
    Do you have a small codesnippet that i can work with and build around? I just cant find a good way to start.

    I would appreciate your help.

    Have great day.



  • @Psyduck0205 hi
    Do you want to use QML/js or python ?
    Can you show what you did already ?



  • You should operate with model data, not with delegates, since they are not actually exists when they get out of ListView viewport.



  • I have to use python.
    I tried work around the object model like InteruderExcluder suggested

    listview = squish.waitForObject(ecusListView)
    model = listview.model
    

    But with that, model is "null"
    I tried to iterate over the Elements but like IntruderExcluder said, i cant past the non visible delegates. So im basicly at 0 again.
    Any help of how i have to work around the model?

    (Squish is basicly an IDE for GUI Testing. Thats what its all About. I Need to make sure that the model or delegates are correct in correlation to the entries in the database.)



  • @Psyduck0205
    a qml js version in case it can help

    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property var myArr : [33,66.6,1.94]
    
        ListModel {
            id: fruitModel
    
            ListElement {
                name: "Apple"
                cost: 800
            }
            ListElement {
                name: "Orange"
                cost: 66.6
            }
            ListElement {
                name: "Banana"
                cost: 1.95
            }
        }
    
        ListView{
            id:l
            model: fruitModel
            anchors.fill: parent
            delegate: Text {
                height: 30
                width: parent.width
                text: name+  " : "+ cost
            }
        }
    
        Component.onCompleted: compare()
    
        function compare(){
            for(var e=0; e < l.model.count; e++){
                console.log( (l.model.get(e).cost === myArr[e]) )
            }
        }
    }
    


  • 		ListView {
    			id: filteredElements
    
    			anchors.fill: parent
    
    			header: Item {}
    			delegate: ListViewDelegate {
    				onClicked: root.filteredClickHandler
    			}
    
    			model: root.controller.filteredModel
    
    			listView.section.property: "shortName"
    			listView.section.criteria: ViewSection.FirstCharacter
    			listView.section.labelPositioning: ViewSection.CurrentLabelAtStart | ViewSection.InlineLabels
    			listView.section.delegate: Component {
    				id: sectionHeading
    				Rectangle {
    					width: parent.width
    					height: childrenRect.height
    					color: Style.rbsDarkGray
    
    					Text {
    						leftPadding: Style.listView.delegate.textPadding
    						text: section
    						font.bold: true
    						font.pixelSize: 10
    						color: Style.rbsLightBlue
    					}
    				}
    			}
    

    I digged trough our bitbucket and managed to finde the Definition of the listview. So that is basicly what i have to work with.
    I dont realy understand how to Transfer the Code of LeLev to python.

    console.log( (l.model.get(e).cost === myArr[e]) )

    Does every l.model has a get() function?

    Without compiling it i tried something:

    listview = squish.waitForObject(ecusListView) #That Returns the objects QQuickListview
    model = listview.model
    maxcount = listview.count
    myarray = []
    for i in range(maxcount):
        myarray.append(listview.model.get(i).text) 
    

    Does that makes sense? Is that the Right way?



  • If it is QML ListModel then yes, it has get method. For C++ models derived from QAbstractItemModel there is data method to retrieve data by role. Also rowCount and index are exposed to QML too.



  • @IntruderExcluder
    Yes it is QML.

    when i try to run it i get the following error:

    Detail AttributeError: 'QVariant' Squish object has no attribute 'get' C:\Users\tsc\repos\rbsplus_guitests\suite_RBS_Plus_Test_Suite\shared\steps\steps.py:333

    Line 333:
    myarray.append(listview.model.get(i).text)



  • I'm not familiar with python, but can give you an example in C++. Lets say you have some ListView with ListModel declared in main QML file:

        ListView {
            objectName: "view1"
            model: ListModel {
                ListElement { prop1: "asd"; prop2: 42 }
            }
        }
    

    Here is an example how to get values for Qt 5.12.3 (it is a bit easier for greater versions):

        /* Get list view */
        auto view = engine.rootObjects()[0]->findChild<QObject*>("view1");
        /* Get model property */
        QQmlListModel* model = view->property("model").value<QQmlListModel*>();
        /* Some magic */
        auto handle = model->get(0);
        auto eengine = qmlEngine(model)->handle();
        QJSValue jsvalue(eengine, handle);
        /* Get values of ListElement item */
        QString prop1 = jsvalue.property("prop1").toString(); // "asd"
        int prop2 = jsvalue.property("prop2").toInt(); // 42
    

    You also need to use qml-private modules, since QQmlListModel is private class.



  • Thank Intruder,

    i understand how that works :)

    The only Problem: I wondered why i couldnt use the get() function. And after a bit of searching i managed to Change the Code to that:

    listview = squish.waitForObject(ecusListView)
    model = object.convertTo(listview.model,"QObject")
    maxcount = listview.count
    myarray = []
    for i in range(maxcount):
        myarray.append(model.get(i).text)    
    

    listview.model Returns a QVariant, which is basicly a container where you put everything in, and let python handle it.
    I then casted the QVariant to QObject to see which class is behind the QVariant.
    Turns out its not QmlLIstModel, its

    https://doc.qt.io/qt-5/qidentityproxymodel.html#details

    And now i have no clue to handle that class and do what i want



  • So, it is C++ model, not QML. Then you can use data method to retrieve data. Something like this:

    for i in range(maxcount):
        myarray.append(model.data(model.index(i, 0), %your_role_here%))
    


  • Hey Intruder thank you for your Reply.

    That brought me close the solution i think.

    The Problem that i have now is: How to deal with the QVariants that are now written in the Array.
    I think i have to cast them first to extract the exact value i want.

    Do you know what i have to do?



  • Depends on what you want. If you have list of QVariant then you can compare them, at least in C++ this works. To compare with exact values you should of course get values from QVariant. For example cast them to integers with toInt() method.


Log in to reply