Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

"fontSizeMode: Text.Fit" in Textfield



  • Is it possible to use "fontSizeMode: Text.Fit" in TextField? I am trying to fit text to rectangle, but it doesn't work as expected. Currently I am using "font.pixelSize" but it doesn't work well when Rectangle is too small.

    I can use other object than TextField. Generally, I want to enter number and I can use any object. I tried to use Spinbox, but I can't set correct size of arrows, background and font.

    Item
    {
        id: main_multi_listview
    
        property var component_value: Qt.createComponent("InfiniteListview.qml")
        property var object_value1: component_value.createObject(mainWindow)
        property var object_value2: component_value.createObject(mainWindow)
        property var object_value3: component_value.createObject(mainWindow)
    
        property var object_separator1: component_value.createObject(mainWindow)
        property var object_separator2: component_value.createObject(mainWindow)
    
        property bool zz: true
    
        TextField
        {
            id: id_XX
            x: object_value2.x
            y: object_value2.y
            implicitWidth: object_value2.width
            implicitHeight: object_value2.height
            visible: true
            font.pixelSize: (Math.min(object_value2.height,object_value2.width) * 1.0)
            clip: true
    
            text: "5"
            horizontalAlignment: TextInput.AlignHCenter
            verticalAlignment: TextInput.AlignVCenter
    
            background: Rectangle
            {
                anchors.fill: parent
                color: "transparent"
                border.color: "red"
                border.width: 1
            }
        }
    

    Left and right object is listview and it works perfectly, but object in center of window is TextField and text is cut when is too small. Text should be resized to be full size in rectangle.
    66ebf7eb-285b-4901-9a0e-28ef5bff854e-obraz.png



  • I found this

            padding: Math.min(height*0.1, width*0.1)
            font.pixelSize: (Math.min(height - topPadding - bottomPadding,width - rightPadding - leftPadding))
    

    and it looks well for one digit. When there are two or more digits, then it doesn't work and digit is cut.
    Second problem is connected with this message:

    qrc:/qml/MultiInfiniteListview.qml:23:5: QML TextField: Binding loop detected for property "font.pixelSize"
    qrc:/qml/MultiInfiniteListview.qml:23:5: QML TextField: Binding loop detected for property "font.pixelSize"
    qrc:/qml/MultiInfiniteListview.qml:23:5: QML TextField: Binding loop detected for property "font.pixelSize"
    

    Any ideas?



  • Hi PawlosCK,

    First, let's review the second message and then the main problem. The problem in your second message is that your binding is broken after receiving the binding loop message.

            padding: Math.min(height*0.1, width*0.1)
            font.pixelSize: (Math.min(height - topPadding - bottomPadding,width - rightPadding - leftPadding))
    

    Basically, the padding depends on the height and width, and the width and height depend on the pixel size, which depends on the padding. Here are some options:

    1 - You need to use a fixed value for the padding.
    2 - Use a javascript function or slot to change the padding values; this during the change of width/height or when you think is pertinent.

    At least this to remove the binding loop.

    Regarding the true source of your problem, you are trying to make a text field fit inside a rectangle:

    First you need to know how QML define the text space:

    TextSize.png

    As example: if you put 40 on your font.pixelSize, QML use 48 pixels of space instead, this because they are considering the space for all the basic Latin characters ("|" is one of the worst cases). Depending on your character set this could affect, but seems like is not the case.

    Recommendations:

    1 - Use a "Text" element instead (contentHeight and contentWidth are useful properties).
    2 - Change the text font.pixelSize on a slot when the text changed or anything you need:

        onTextChanged: {
               // change the font.pixelSize
        }
    

    3 - If nothing of this is a plausible solution, give us more information to finish helping you.

    Regards,



  • This is how we are sizing and centering text of variable size:

                Text {               
                    text: sometext
    
                    width: somewidth
                    height: someheight
                    font.pointSize: 25
                    minimumPointSize: 2
                    fontSizeMode: Text.Fit
    
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }