[solved] script in property



  • hello, my name is Steven and i'm new to QT and quite new to programming in general, so this won't be the last post by me hehe.

    so i want a listview with information about the device the app is running on, with screen info, device info etc.
    but i can't put Screen.screenwidth, Screen.height or Screen.pixelDensity in a list element because its a script and it needs to be a property, if i understand correctly.

    this is the bit of code i use:
    @
    Rectangle {
    width: Screen.width; height: Screen.height

        ListModel {
            id: infoModel
            property int screenWidth: 1
            ListElement {
                name: "Screen width"
                info: Screen.width
            }
            ListElement {
                name: "Screen height"
                info: Screen.height
            }
            ListElement {
                name: "pixel density"
                info: Screen.pixelDensity
            }
        }
    
        Component {
            id: infoDelegate
            Row {
                    id: infor
                    Text { text: name + ": " ; color: infor.ListView.view.infor_color }
                    Text { text: info }
            }
        }
    
        ListView {
            property color infor_color: "green"
            model: infoModel
            delegate: infoDelegate
            anchors.fill: parent
        }
    

    @
    so,
    info: Screen.width
    info: Screen.height
    info: Screen.pixelDensity
    doesn't work while stuff like
    info: 1
    does work.

    any help, feedback, examples is welcome

    thanks in advance!


  • Moderators

    Hi,

    You understood correctly. More details "here":http://qt-project.org/doc/qt-5/qml-qtqml-models-listelement.html#details
    Going by your current implementation, you will need to handle that at delegate level.



  • You could add the list elements dynamically. For example add a function like this:
    @function fillScreenProps () {
    infoModel.append({"name":"Screen width", "info": Screen.width})
    infoModel.append({"name":"Screen height", "info": Screen.height})
    infoModel.append({"name":"pixel density", "info": Screen.pixelDensity})
    }
    @

    Then in your Rectangle you could invoke the function
    @ Rectangle {
    Component.onCompleted: fillScreenProps()
    width: Screen.width; height: Screen.height
    //...@



  • this is what i have now @ Component {
    id: infoDelegate
    Row {
    id: infor
    Text { text: assign(index, 2) + ": " ; color: infor.ListView.view.infor_color }
    Text { text: assign(index, 1) }

            }
        }
    
        ListView {
            property color infor_color: "#7dfafa"
            model: 50
            delegate: infoDelegate
            highlight: Rectangle { color: "lightsteelblue"; radius: 6 }
            focus: true
            anchors.fill: parent
    
        }
    }
    
    function assign(number, type){
    
        var a;
        var b;
    
        switch (number){
        case 0 :
            a=Screen.width; b="Screen pixel width"; break;
        case 1 :
            a=Screen.height; b="Screen pixel height"; break;
        case 2 :
            a=Screen.pixelDensity.toFixed(2); b="Screen pixel density"; break;
        case 3 :
            a=rect.x; b="rectangle X-coördinates "; break;
        case 4 :
            a=rect.y; b="rectangle Y-coördinates"; break;
        case 5 :
            a=rect.opacity.toFixed(2); b="rectangle opacity"; break;
        case 6 :
            a=rect.color; b="rectangle color"; break;
        case 7 :
            a=Screen.orientation; b="Screen orientation"; break;
        case 8 :
            a=backpressed; b="times back is pressed"; break;
        case 9 :
            a=xtonumber(sliderect.x).toFixed(2); b="times needed to go back"; break;
        case 10 :
            a=orientationToString(Screen.primaryOrientation); b="Screen orientation"; break;
        case 11 :
            a=Screen.logicalPixelDensity.toFixed(2); b="logical pixel density"; break;
        case 12:
            a=Screen.name; b="screen name?"; break;
        case 13:
            a=c;b="time in this page in ms"; break;
        default:
            a=0; b=""; break
        }
        if (type === 1) return a;
        else return b;
    }@
    

    this works well, thanks for the advice and the help!



  • I think it would be cleaner (just an opinion) to use a couple of functions to populate the ListModel. You would of course need to add a line to fillScreenListModel() for every additional item you added in your case statement.
    @ function makeObject(roleName, value)
    {
    return {"name": roleName, "info": value}
    }

    function fillScreenListModel()
    {
        var dataArray = [],
                i=0
        dataArray[i++] = makeObject("Screen width",Screen.width)
        dataArray[i++] = makeObject("Screen height",Screen.height)
        dataArray[i] = makeObject("Pixel density",Math.floor(Screen.logicalPixelDensity*100)/100)
        //Now move each object into the ListModel
        dataArray.forEach(function(element){infoModel.append(element)})
    }@
    

    Then your ListModel could look like this:
    @ ListModel {
    id: infoModel
    Component.onCompleted: fillScreenListModel()
    }@

    If you want to format pixelDensity as a string using toFixed(2), then add toString() to the other numbers so that all the info roles are strings.


Log in to reply
 

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