Solved Line-Height of Text in TextArea !
-
@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? -
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 usingfont.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 -
@AnonymousCoder said in Line-Height of Text in TextArea !:
@sierdzio Just now I calculated the Textarea's height .It showed me 66 px .
But usingfont.pixelSize:22px
22
, nopx
- 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" -
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 .
-
@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.heightYou 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
andcontentWidth
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 onlyTextArea{}
and itsbackground: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:
liketext: "<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 fromQTextDocument
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 theundo, redo
operations won't work . They will only work again when I doselect-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 containssetUndoRedoEnabled(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, '&').replace(/</g, '<').replace(/>/g, '>'); } 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();
-
Hey @sierdzio
I have found the solution to this generic issue which is "How to achieve line - height of Text in Textarea or Textbox or Textedit (Editable items) ?" .
Actually frankly speaking we don't have a direct solution for this so we will use something which is a bit complicated.Based on my previous comment I would like to add something that the above code is the solution for this issue but there we will have to add some more 2-3 lines of code because previous solution has some issues actually.
Main.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, '&').replace(/</g, '<').replace(/>/g, '>'); } 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 ) ) { event.accepted = true; pasted = true; } } Keys.onReleased: { if ((event.key === Qt.Key_V) && (pasted)){ event.accepted = true; pasted = false; tdoc.pasteText(cursorPosition, selectionStart, selectionEnd); } } TextDoc { id: tdoc } Component.onCompleted: { tdoc.setTDoc(ta.textDocument); tdoc.onCompleted(pix); } } } }
TextDoc.h
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 pasteText(int pos, int selectionStart, int selectionEnd); 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); } void TextDoc::pasteText(int pos, int selectionStart, int selectionEnd) { const QString text = QGuiApplication::clipboard()->text() if(text.isNull()) { return; } QTextCursor theCursor(tDoc->textDocument()); if(selectionStart >= 0 && selectionEnd >= 0) { theCursor.setPosition(selectionStart, QTextCursor::MoveAnchor); theCursor.setPosition(selectionEnd, QTextCursor::KeepAnchor); } else { theCursor.setPosition(pos); } theCursor.beginEditBlock(); theCursor.insertText(text); theCursor.endEditBlock(); } TextDo::TextDo(QObject *parent) { } void TextDo::registerQmlType() { qmlRegisterType<TextDo>("TextDoc", 1, 0, "TextDoc"); }
In Main.cpp just add 1 more statement
TextDo::registerQmlType();
Therefore in the above code you can see I have added one more function to TextDoc class which is pasteText() , it actually pastes the text to the clipboard and then tries to apply other clipboard operations.
So this solution is working fine for me and I hope it works for others too.Thanks @sierdzio for helping me and others who are watching this thread.