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

[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