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

Line-Height of Text in TextArea !



  • Hi ! Actually I am stuck in a situation where I have a condition of line-Height and I am not able to use it in my TextArea code .
    My Textarea is inside Flickable which is further inside a Rectangle .
    I want my Rectangle to be of 288 and 78 width and height. And the line-Height is given 22px.
    I am finding troubles in handling this . So Please try to help me .
    And ignore the codes for Mouse Area .
    Thanks in Advance !
    TextWidget.qml

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQml 2.12
    
    
    
    Rectangle {
        id: parentrect
    
        property alias textContent:textarea.text
          property alias fieldlabel:childrecttext.text
            property  int paintedHeight:22
    
        width:288
        height:paintedHeight*3
           
    
        border.color: "green" 
        color: "gray"
       
        Flickable {
            id:flickitem
            contentWidth: textarea.width
            contentHeight:textarea.height
            anchors.fill: parent
            TextArea.flickable:  TextArea {
                id:textarea
                focus: true
               // height: 22*textarea.lineCount
                hoverEnabled: true
                //anchors.fill:parent
    
                wrapMode: TextArea.WrapAtWordBoundaryOrAnywhere
                font.pixelSize: 16
                font.family: "Times New Roman"
                leftPadding: 12
                rightPadding: 12
                topPadding:6
                bottomPadding: 6
    
    
                onTextChanged: {
                parentrect.height=(lineCount*parentrect.paintedHeight)+parentrect.paintedHeight
    
                }
                onReadOnlyChanged: { btextreadonly=textarea.readOnly }
                selectByMouse: true
                textFormat: TextArea.AutoText
    
               Component.onCompleted: { console.log(textarea.paintedHeight)
                                        console.log(parentrect.width)
                                        console.log(parentrect.height)
                                        console.log(childrecttext.paintedHeight)
                                        console.log(textarea.lineCount)
               }
    
    
      /* Function to get Active Focus on Textarea  */
    
                function activate() {
                       if(textarea.activeFocusOnPress)
                           textarea.forceActiveFocus()
                   }
            }
    
                 ScrollBar.vertical: ScrollBar{
                  active: hovered || pressed
                  policy: ScrollBar.AlwaysOn
    
                 }
        }
    
    
    
        Rectangle {
            id:labelrect
            height: childrecttext.contentHeight
            width: childrecttext.contentWidth
            color: "white"
            anchors{
                bottom: parentrect.top
                left: parentrect.left
                right: parentrect.right
                bottomMargin: 8
            }
            Text {
            id: childrecttext
            anchors.fill: parent
            lineHeight: 22
            lineHeightMode: Text.FixedHeight
            font{
            pixelSize: 14
            family:"Times New Roman"
            }
            wrapMode: Text.WordWrap
            color: "black"
        }
    
        }
    
    
    
    
        MouseArea {
            id:mousearea
            anchors.fill: parent
            hoverEnabled: true
            cursorShape: Qt.IBeamCursor
            onEntered:
            {
                parentrect.state = "Entered";
    
            }
            onExited:
            {
                parentrect.state = "Exited";
            }
            onClicked:
            {
                   textarea.activeFocusOnPress =btextreadonly?false: true;
                    textarea.cursorVisible=true;
                    textarea.activate();
            }
             onPressAndHold: {
    
                    if (mouse.source === Qt.MouseEventNotSynthesized) {
                        selectStart = textarea.selectionStart;
                        selectEnd = textarea.selectionEnd;
                        curPos = textarea.cursorPosition;
                        textarea.cursorPosition = curPos;
                        textarea.select(selectStart,selectEnd);
                     }
                 }
            onDoubleClicked: textarea.selectWord()
           }
    
    
    
              states: [
                State
                {
                    name:"Entered"
                    PropertyChanges
                {
                    target:parentrect;
                    border.color:parentrect.btextreadonly? "black":"blue"
    
                }
            },
                State
                {
                name:"Exited"
                PropertyChanges
                {
                    target:parentrect;
                    border.color:parentrect.btextreadonly?"black":"green"
                }
             }
              ]
    
    
    
    }
    
    
    
    

    Main.qml

    ```import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Window 2.12
    Window{
    width: 800
    height: 400
    visible: true
    title: qsTr("TextBox")
    
    Rectangle{
        id:rect1
        width : parent.width/2
        height: parent.height
        color: "White"
    
        Row{
            id:lightThemerow1
             x:10
             anchors.top:  parent.top
             anchors.topMargin: 200
             spacing: 20
        TextWidget{
              id:textarea1
    
              fieldlabel:"Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusmod tempor."
    
              textContent:"Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusmod tempor incididunt ut labor."
    
        }
    }
    }
    
    }
    

  • Moderators

    @AnonymousCoder said in Line-Height of Text in TextArea !:

    TextArea.flickable: TextArea {

    Just TextArea {.

    And it should have width defined to some fixed value (same as your parent rectangle). Then, uncomment what you have in height and it should work.

    There is a lot of extra code here, it's hard to debug. Maybe try distilling this into a minimal example, even in a separate app - just to get it to work. Then you can start adding all that extra stuff back in, step by step.



  • @sierdzio I tried but the line height is still 20px only .It is not changing to 22px . Please have a look at the code .
    Also how can I change the painted Height of TextArea ?

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQml 2.12
    
    
    Rectangle {
        id: parentrect
          property alias textContent:textarea.text
          property  int paintedHeight:22
          width:288
          height:78
          border.color: "green"
          color: "white"
    
        Flickable {
            id:flickitem
            contentWidth: textarea.implicitWidth
            contentHeight: textarea.implicitHeight
            anchors.fill: parent
            boundsBehavior: Flickable.StopAtBounds
            flickableDirection: Flickable.VerticalFlick
            interactive: true
    
            ScrollView{
            id:scroll
            anchors.fill: parent
            height: parent.height
            width: parent.width
    
            TextArea{
                id:textarea
                focus: true
                anchors.fill: parent
                implicitWidth: 288
                implicitHeight:  22*textarea.lineCount
                //height:
                wrapMode: TextArea.WrapAtWordBoundaryOrAnywhere
                font.pixelSize: 16
                font.family: "GE Inspira Sans"
                leftPadding: 12
                rightPadding: 12
                topPadding:6
                bottomPadding: 6
                textFormat: TextArea.AutoText
    //            onTextChanged: {
    
    //            }
               Component.onCompleted: { console.log(textarea.paintedHeight)
                                        console.log(parentrect.width)
                                        console.log(parentrect.height)
                                        //console.log(childrecttext.paintedHeight)
                                        console.log(textarea.lineCount)
               }
    
    
    
            }
    }
    
        }
    
    
    }
    [Here is the link of images on which I am working][(https://drive.google.com/drive/folders/1FTvkbzDkpll37BSWHkSZtPFVQTdIVx3i?usp=sharing)]

  • Moderators

    Don't worry about paintedHeight and implicitHeight for now, just use regular height.

    Also how can I change the painted Height of TextArea ?

    By modifying font size, adding more text, changing max number of lines, changing wrapping etc. There are many many ways.



  • @sierdzio Yes Even I did that ..Changed to regular height but when I calculate paintedHeight in Console.log() function it is still showing me 60 which means line-height is still 20px right?
    And how do I check that line height is changed?


  • Moderators

    And what does height show? Is it also 60?

    Maybe set font size in pixels instead of font size? font.pixelSize: 22



  • @sierdzio Just now I calculated the Textarea's height .It showed me 66 px .
    But using

    font.pixelSize:22px
    

    The rectangle's height is changing to 108

    console.log(textarea.paintedHeight)
    console.log(parentrect.width)
    console.log(textarea.heigh
    console.log(parentrect.height)
    console.log(textarea.lineCount)
    QML Flickable: Binding loop detected for property "height"
    qml: 60
    qml: 288
    qml: 66
    qml: 78
    qml: 3


  • Moderators

    @AnonymousCoder said in Line-Height of Text in TextArea !:

    @sierdzio Just now I calculated the Textarea's height .It showed me 66 px .
    But using

    font.pixelSize:22px
    

    22, no px - it's just a number.

    The rectangle's height is changing to 108

    That's probably because of all the padding you've added.



  • @sierdzio This was the result earlier .

    console.log(textarea.paintedHeight                     qml: 60
    console.log(parentrect.width)                                qml: 288
     console.log(textarea.height)                                   qml: 66
      console.log(parentrect.height)                               qml: 78
       console.log(textarea.lineCount)                            qml: 3
    

    And also this statement .Could you please clarify?
    QML Flickable: Binding loop detected for property "height"


  • Moderators

    QML Flickable: Binding loop detected for property "height"

    That means you set some property, which updates another, which sets the first prop again etc. - an infinite loop.

    Hey wait, why is there a ScrollView there? Remove it, you don't need it. It is very likely to mess up with the logic here.



  • @sierdzio Okay as You said I have removed the ScrollView But then If the text is more than the height of the Rectangle then it should scroll right .

    So I have added ScrollBar inside Flickable .

    Flickable {
           id:flickitem
           width: textarea.width
           height: textarea.height
           anchors.fill: parent
           boundsBehavior: Flickable.StopAtBounds
           flickableDirection: Flickable.HorizontalFlick
           interactive: true
           ScrollBar.vertical: Scrollbar{}
    TextArea{...}
    

    Scrollbar.qml

    ScrollBar {
        id: control
        size: 0.3
        position: 0.2
        active: true
        orientation: Qt.Vertical
        anchors.right: parent.right
    
        contentItem: Rectangle {
            implicitWidth: 4
            implicitHeight: 76
            radius: width / 2
            color: control.pressed ? "#81e889" : "#c2f4c6"
        }
    }
    

    But still it is not scrolling .


  • Moderators

    @AnonymousCoder said in Line-Height of Text in TextArea !:

    Scrollbar.qml

    You don't need that, there is https://doc.qt.io/qt-5/qml-qtquick-controls2-scrollbar.html. As said, keep custom code to minimum until you make it work.

    Flickable {
    id:flickitem
    width: textarea.width
    height: textarea.height

    You set TextArea size to be the same as Flickable - so there is nothing to scroll - the entire text area will be shown.

    You need to make the Flickable smaller than TextArea, then set Flickable's contentHeight and contentWidth to match that of TextArea.



  • This post is deleted!


  • @sierdzio As you said I kept the code as minimum as possible and I tried to do it from scratch.
    so for now I have given only TextArea{} and its background:Rectangle{}

    Which I have shared here with the results.

    TextArea{
            id:area
            width: 288
            height: 22*area.lineCount
            font.pixelSize: 16
            font.family: "GE Inspira Sans"
            topPadding: 6
            bottomPadding: 6
            leftPadding: 12
            rightPadding: 12
            text: "Lorem ipsum dolor sit amet, conse ctetur adipiscing elit, sed do eiusmod tempor incididunt ut labor."
            wrapMode: TextArea.WordWrap
            background: Rectangle{
                id:rect
                width: 288
                height: 78
                border.color: "black"
            }
            Component.onCompleted: {
                console.log(area.paintedHeight)
                console.log(area.height)
                console.log(rect.height)
    
            }
    
         }
    

    Results :

    qml: 60
    qml: 66
    qml: 78
    

    And suppose if I get line-height correctly also then how should I check whether it is correct or not?
    Is there any way to implement Html here in TextArea?

    Also I have shared a link to images which I need ( See images with Black background) and those with the above code (see images with white background).
    Click here



  • @sierdzio Hi , Actually I tried many ways but I got something which is not fully working but still 50% of work is fine .

    i am using css property inside text: like

    text: "<body style=\"line-height:137.5% ;\">"
    

    but i am not sure this is the correct way to do or not .
    And now the issue is when I use 137.5% which is 22px line-height then always the 3rd line comes half when the application runs .
    So how to fix that ?



  • HI @sierdzio and anyone who is watching this thread.
    I got one solution on how to achieve line-height of text inside TextArea.
    I took help from QTextDocument and tried to use it but there is one limitation with this solution.
    Actually when I tried to use the keyboard operations (undo,redo,cut,copy,paste,select-all) then every operation is working but when i tried paste operations (cut-paste, copy-paste ) then the undo, redo operations won't work . They will only work again when I do select-all operation. so this is the limitation with this solution.

    Now When you see the code in TextDoc.cpp there you will find 2 statements which contains setUndoRedoEnabled(false) & setUndoRedoEnabled(true) . Here the question arises that why playing with Undo, Redo is needed ? So the answer is its needed because if I dont give these lines then after the paste operation the line-height property is lost ...therefore to achieve it we need that .

    Again the issue is still "How to achieve line-height of Text in TextArea?" But if you have solution to the above Undo , Redo issue ...Then please help .
    Thanks !

    Mail.Qml

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.12
    import TextDoc 1.0
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
        property int cursor_pos: 0
        property bool pasted: false
        property int prev_len: 0
        property int pix: 50
    
        function fun(s) {
            return (s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        }
    
        ScrollView {
            y:200
            clip: true
            width: 600
            height: 400
    
            TextArea {
                id: ta
                width: 600
                height: 400
                wrapMode: Text.WrapAnywhere
                textFormat: TextEdit.PlainText
                placeholderText: "Hint Text"
                text: "sdfffffffffffffff dsf sdf sdf \n sdfdsfdsffsd\n dsfdsfdsfdsfdsfdsfdfdsfsdfdssssssssssssssssssssssssssssss"
                font.pixelSize: 16
                font.family: "courier"
                background: Rectangle {
                    width: 600
                    height: 400
                    border.color: "blue"
                }
                Keys.onPressed: {
                    if ( (event.key === Qt.Key_V) && (event.modifiers  & Qt.ControlModifier ) ) {
                        pasted = true;
    
                    }
                }
                Keys.onReleased: {
                   if ((event.key === Qt.Key_V) && (pasted)){
                       pasted = false;
                       tdoc.onCompleted(pix);
                   }
                }
    
                TextDoc {
                    id: tdoc
                }
    
                Component.onCompleted: {
                    tdoc.setTDoc(ta.textDocument);
                    tdoc.onCompleted(pix);
                }
    
    
            }
        }
    }
    
    

    TextDoc.h

    #include <QTextDocument>
    #include <QQuickTextDocument>
    #include <QDebug>
    
    class TextDo : public QObject
    {
    Q_OBJECT
    public:
        explicit TextDo(QObject* parent = nullptr);
    
        static void registerQmlType();
    
        Q_INVOKABLE void onCompleted(int c);
    
        Q_INVOKABLE void setTDoc(QQuickTextDocument* newTDoc) {
            qDebug() << "setTDoc called";
    
            tDoc = newTDoc;
        };
    
    private:
        QQuickTextDocument *tDoc;
    };
    
    

    TextDoc.cpp

    #include "TextDoc.h"
    #include <QTextFrame>
    
    
    void TextDo::onCompleted(int c)
    {
        qDebug() << "onCompleted called";
    
    
        tDoc->textDocument()->setUndoRedoEnabled(false);
    
        QTextBlockFormat blockFmt = QTextBlockFormat();
        blockFmt.setLineHeight(c, QTextBlockFormat::FixedHeight);
    
        QTextCursor theCursor(tDoc->textDocument());
        theCursor.clearSelection();
        theCursor.select(QTextCursor::Document);
        theCursor.mergeBlockFormat(blockFmt);
    
        tDoc->textDocument()->setUndoRedoEnabled(true);
    }
    
    TextDo::TextDo(QObject *parent)
    {
    
    }
    
    void TextDo::registerQmlType()
    {
        qmlRegisterType<TextDo>("TextDoc", 1, 0, "TextDoc");
    }
    
    

    In Main.cpp just add 1 more statement

    TextDo::registerQmlType();
    

Log in to reply