I've got two requirements for a custom Text element in QML:
1. Select and copy text
I'd like to display text and allow the user to copy it by selecting it with the mouse and copy via CTRL+C.
-> This works out-of-the-box by using a TextEdit/TextArea element with "readOnly" and "selectByMouse" both set to true.
2. Adjust text's line height
I'd like to be able to adjust the text's line height.
-> Seems NOT possible with TextEdit/TextArea.
-> Can be adjusted in a normal Text element by setting "lineHeight". But Text cannot be selected and copied by the user.
Is there a way to adjust either of the elements to perform the missing task?
What is the typical solution for this? Seems to be a simple enough requirement but I cannot find it discussed anywhere.
Edit:
Going by SMR's comment, I checked out the approach of setting it to RichText mode and modifying the content to set the line height. This is the richtext string of a multiline text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
li.unchecked::marker { content: "\2610"; }
li.checked::marker { content: "\2612"; }
</style></head><body style=" font-family:'Segoe UI'; font-size:15px; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Line one Line two Line three</p></body></html>
I extended the paragraphs' style by line-height inside of "Component.onCompleted()":
text.replace("text-indent:0px;", "text-indent:0px; line-height:" + desiredLineHeightInPx + "px;")
This works, but also puts whitespace above the first line. I tried to counteract that by setting a negative top margin, with no success:
var marginToCounteractLineHeight = desiredLineHeightInPx / 2
newText = text.replace("<p style=\" margin-top:0px;", "<p style=\" margin-top:-" + marginToCounteractLineHeight +"px;")
For now, I opted to use the Text element and put a MouseArea on top to transfer the text to an invisible TextEdit, on which I then select all and copy to clipboard (followed by an animation to inform the user):
MouseArea {
acceptedButtons: Qt.LeftButton
onClicked {
// Copy to TextEdit
myInvisibleTextEdit.text = myText.text
myInvisibleTextEdit.selectAll()
myInvisibleTextEdit.copy()
copyAnimation.start()
}
}
[REWRITE]
Your TextEdit
should already implement "CTRL+C" keyboard shortcut. If it's not working, you can declare an "CTRL+C"
action for it. As to controlling TextEdit
line height, you can set your textFormat: Text.RichText
and supply an HTML body with style set to line-height:2
TextEdit {
id: textEdit
text: `<body style="line-height:2">Hello World<br>
Mary had a little lamb</body>`
textFormat: Text.RichText
font.pointSize: 12
Action {
text: "copy"
shortcut: "Ctrl+C"
onTriggered: textEdit.copy()
}
Component.onCompleted: select(3, 10)
}
You can Try it Online!