Updating fontSize via function key call - calling functions in QML



  • I have a listview on which I need to dynamically update the font size when the F2 key is pressed. The XML document containing the listview data is quite complicated (speech, Braille and voice recognition are required) so it handled by the c++ code (coreMenu) making the QML really simple. The Qt documentation shows how to create a function and call it but is for a signal/slot and is all within one simple rectangle. Is there to a way access functions within a component when you are outside a component? I have not been able to find an example and I cannot work out the exact syntax :-S

    @
    import QtQuick 2.0

    Rectangle
    {
    id: theMenu
    Component
    {
    id: menuEntryDelegate

        Rectangle
        {
            id: menuItemContainer
            width: menuHolder.width
            height: menuEntry.height * 1.25
            anchors.top: prompts.bottom
            function setFont(fontSize)/********** where does this function go??************/
            {
                menuEntry.font.pointSize = fontSize
            }
    
            state: ListView.isCurrentItem ? "selected" : "notselected"
    
            Text
            {
                id: menuEntry
                font.pointSize: coreMenu.menuFontPointSize
                width: parent.width
                wrapMode: Text.WordWrap
                text: displayText
                clip: true
            }
    

    .......

    }
    
    Rectangle
    {
        id: menuContainer
        width: coreMenu.menuWidth
        height: (50 * 9)
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: prompts.bottom
        color: "purple"
        ListView
        {
            id: menuHolder
            model: menuModel
            anchors.fill: parent
            opacity: 1
    
           header: Rectangle
            {
                width: menuHolder.width
                height: 50
                color: "#2A51A3"
    
    
               Text
                {
                   id: header
                   anchors.centerIn: parent
    
                   text: coreMenu.getMenuTitle()
                   font.pointSize: 20
                   color: "green"
                   width: parent.width
                   wrapMode: Text.WordWrap
                }
            }
    
            delegate: menuEntryDelegate
            focus: true
    
            Keys.onPressed:
            {
                if(event.key === Qt.Key_F1)
                {
                    theMenu.visible = false
                }
                else if(event.key === Qt.Key_F2)
                {
                    coreMenu.menuFontPointSize *= coreMenu.scale
    

    /******** want to update the font here - i.e. menuEntry.font.pointSize***********/
    }
    ..............
    }
    @

    If I put the function here
    @
    Rectangle
    {

    function setFont(fontSize)
    {
        menuEntry.font.pointSize = fontSize
    }
    
    id: theMenu
    Component
    {
    

    @

    it compiles, runs and hits a brake point but outputs runtime errors:

    file:///C:/Projects/GuideNext/qml/GuideNext/Menu.qml:11: ReferenceError: menuEntry is not defined
    file:///C:/Projects/GuideNext/qml/GuideNext/main.qml:52: ReferenceError: menuContainer is not defined



  • Hi,

    Id's are unique within a component, but not accessible from outside the component.
    Thus, "theMenu" will resolve to the top-level Rectangle from within the menuItemComponent's scope, but "menuItemComponent" will not resolve if used outside of the "menuEntryDelegate" component.

    Declaring a function in an object declaration (such as your setFont() function in the menuItemContainer Rectangle) will add a function attribute to that object instance's implicit type. You can call it as you would any other function. However, you need to be able to reference that function somehow, and this is often tricky with delegates.

    Usually, a better way is (instead of calling the function directly) to set a property to which you have a binding in the delegate.

    eg:

    @
    Item {
    id: root
    property int fontSize

    Component {
        id: delegateComponent
        Rectangle {
            id: delegateRect // this id is not resolvable from anything outside delegateComponent
            property int fontSize: root.fontSize // can resolve "root" since we're inside root's component
        }
    }
    
    Keys.onPressed: if (event.key == Qt_F2) root.fontSize = root.fontSize + 1
    

    }
    @

    Cheers,
    Chris.



  • Thought that was probably the case but did not know how to get round it. Property is an excellent idea thanks :-)

    Have a good weekend.



  • One last thing. Any thoughts on how I would use the same variable idea to sort the menuEntry width? When changing the font size I need the width of menuEntry to be the font width but all the strings are different lengths so really I want the width to be the width of the largest string

    @ Rectangle
    {
    id: menuItemContainer
    width: menuEntry.width /automatically sizes but here for each entry but I need to use a var so I can store the largest width of an entry and it in the F2 key stroke/
    height: menuEntry.height * 1.25
    anchors.top: prompts.bottom
    property double fontSize: theMenu.fontSize

            state: ListView.isCurrentItem ? "selected" : "notselected"
    
            Text
            {
                id: menuEntry
                font.pointSize: fontSize
                //width: parent.width
                wrapMode: Text.WordWrap
                text: displayText
                clip: true
            }
    

    @



  • Hi,

    Similar code to the fontSize one: give root a "maxWidth" property. In each delegate, on f2, do:

    @
    var newWidth = (font metrics for each character in the string at the given font size);
    if (root.maxWidth < newWidth) {
    root.maxWidth = newWidth;
    }
    @

    Then you can bind your menuEntry's width to be the root.maxWidth value.

    Cheers,
    Chris.



  • Thank you. That was what I was doing but there was a typo blush


Log in to reply
 

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