How to prevent typing whitespace in TextEdit QML? - qt

How to prevent typing whitespace in TextEdit? QML
TextEdit {
width: 240
text: "123"
font.pointSize: 20
color: "blue"
}

if you can change text input item from TextEdit to TextInput can use validator and regular expressions
from doc :
The RegExpValidator type provides a validator, which counts as valid any string which matches a specified regular expression.
in another way can get the onTextChanged signal and remove whitespace :
like this :
TextEdit {
width: 240
text: "123"
font.pointSize: 20
color: "blue"
onTextChanged:text = text.replace(/\s+/g,'')
}

Related

Add hint to QML TextField with maximum length?

I have a QML TextField where the user can input a limited amount of characters. Is there a way to add a simple hint like so? It can be inside the input too (as uneditable text, of course), or next to it.
ColumnLayout {
Label {
text: "Short description"
}
TextField {
Layout.fillWidth: true
maximumLength: 30
}
}

Is there a way to replace <img> tags with alternate text in selectedText property of QML TextEdit

I have a TextEdit component used to show text messages. When parsing messages I replace common emoticons shortcuts with emojis using <img> tag and setting textFormat: TextEdit.RichText on my TextEdit component. When somebody copies a message containing an emoji, selectedText attribute of TextEdit inserts an OBJECT REPLACEMENT CHARACTER 0xFFFC instead of selected <img> tag.
Example:
import QtQuick 2.9
import QtQuick.Controls 2.2
Item {
id: root
width: 500
height: 500
TextEdit {
id: myTextEdit
anchors.centerIn: parent
text: "Test <img src=\"app.icns\"></img> image"
textFormat: TextEdit.RichText
readOnly: true
selectByMouse: true
onSelectedTextChanged: {
console.log(selectedText);
}
}
}
When you select everything inside of the myTextEdit it prints "Test  image". Is there a way to specify some other way of replacing <img> in selectedText so I can choose some alternate text instead of 0xFFFC.
You can use selectionStart and selectionEnd to get the actual text in that range from text instead of relying on the value of selectedText.
Something like:
console.log(text.slice(selectionStart, selectionEnd));

How to programmatically append text to a QML TextArea?

I am trying to pass log data to my QML front end, one line at a time, and have it append to the end of a TextArea. I've considered several approaches. The following is the most promising. I have created a QAbstractListModel (in Python) and pass this model into a repeater where it arrives as a single item (rowCount =1) which I append to the TextArea using the line
text: terminal_text.text + display
This works but I get this warning everytime the text is updated.
file://.../TextArea.qml:728:9: QML QQuickTextEdit*: Binding loop detected for property "text"
See below for the code of the repeater.
Repeater {
model: TerminalFeed { }
delegate: TextArea {
id: terminal_text
font.family: "Courier"
width: parent.width
height: parent.height
readOnly: true
selectByMouse: true
wrapMode: TextEdit.NoWrap
horizontalScrollBarPolicy: Qt.ScrollBarAsNeeded
verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
text: terminal_text.text + display
}
}
How can I stop this happening? Alternatively does anyone have a better way of achieving the same result?
Technically, that is indeed a binding loop because text is dependent on its own value. If QML didn't detect it and break it, an infinite loop of updating would result.
Instead of using a binding, you can do something like this:
Repeater {
model: TerminalFeed { }
delegate: TextArea {
id: terminal_text
font.family: "Courier"
width: parent.width
height: parent.height
readOnly: true
selectByMouse: true
wrapMode: TextEdit.NoWrap
horizontalScrollBarPolicy: Qt.ScrollBarAsNeeded
verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
onDisplayChanged: {
text = text + display;
}
}
}
With the original binding approach, it will try and update whenever either display or text changes. With this approach, it will only try and update whenever display changes – which is what you really want.
I had a similar problem where I wanted to show logged data in a QML window.
I use the insert() method, which is inherited from QML TextField. The insertion position is the length of the TextArea.
TextArea {
id: outputTextArea
}
Component.onCompleted: {
data = "dummyString"
outputTextArea.insert(outputTextArea.length, data)
}

how to get set font of text with another text's font

I have two Text items in qml and I want to set font of first text to the font of second text. How can I do that?
e.g
Text{
id:t1
//some code
//anchors ..etc
}
Text{
//set font = t1.font or something similar
}
You are almost there, you need to use colon : to assign the property:
Text {
id: txt1
font.bold: true
text: "Hello"
}
Text {
id: txt2
font: txt1.font
text: "World"
}

How do you select a character from text in Qt?

I've uploaded a text file and parsed the content into a text object. Eventually I will be passing each character in the string to a rectangle of its own. I am trying to figure out how to pick a character from the string in qml?
For example:
//Assume the text is already parsed from the file and it is stored in the object below
Text {
id:myText
text: "The quick brown fox jumps over the lazy dog"
visible:false
}
// And now i would like to transfer the first letter into a rectangle
Rectangle{
id: firstRect
width:rectText.width
height:rectText.height
color: "yellow"
Text {
id:rectText
text: // How do I set this as the first character 'T'
font.pixelSize: 14
color: "black"
}
}
How can set the rectangle with the character from myText to rectText ?
Eventually I will be setting each character in a rectangle of its own.
It is close to impossible. At least not by using what little font metrics functionality is provided to QML. There is TextMetrics available since Qt 5.4, but for some reason it didn't report the text size accurately, at least for the fonts that I've been using. It may have to do with this issue. I ended up getting accurate results by appending the 字 character to the queried text, and I don't even want to go into detail how I figured that out.
And then, if that happens to work, you only have the text dimensions, but no way to determine the position of that rectangle, since QML text elements can only give you the cursor position, but not the position of any particular character. If you have a single line of text it could be doable - just calculate the width of the preceding text, but for multi line it is a no-go.
You will probably have to take a very different approach. Maybe implement an adapter that presents strings as list models, and you represent every individual character as a QML element in something like a flow view.
But having a discrete visual item for every character will be huge overhead for long text, so if you are going to have such text, you will also have to handle a model proxy that only displays a particular portion of the text.
I can currently think of no other way to get accurate information about the position and size of text character. The API simply doesn't have that functionality.
There is a simple example that is perfectly applicable for short text:
ApplicationWindow {
id: main
width: 640
height: 480
visible: true
property var charlist: textfield.text.split('')
property int currentChar: 0
Column {
TextField {
width: main.width
id: textfield
text: "example text"
}
Flow {
width: main.width
height: 200
Repeater {
model: charlist
delegate: Rectangle {
Text { id: tt; text: modelData; font.pointSize: 20 }
width: tt.width
height: tt.height
color: "red"
border.color: index === currentChar ? "black" : "red"
MouseArea {
anchors.fill: parent
onClicked: {
currentChar = index
var pos = mapToItem(main.contentItem, 0, 0)
info.text = "rectangle x y w h: " + pos.x + ", " + pos.y + ", " + width + ", " + height
}
}
}
}
}
Text {
id: info
}
}
}
You can enter arbitrary text in the text field, which will be represented by a model view that creates an item for every character. Clicking a character will "select" it and will also give you the rectangle values corresponding to its position in the application window.

Resources