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"
}
Related
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
}
}
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));
I have created a Rectangle item with Text item in center which acts as Edit box with Cursor item at the end of the text.
So for Orientation to be taken care by QML, I have modified the Text item as
Text
{
id: text_input
font.bold: true
font.pixelSize: 22
color: "white"
text: view.defaultTextField
elide: Text.ElideLeft
verticalAlignment: Text.AlignVCenter
anchors.fill: parent
maximumLineCount: 1
clip: true
anchors{
rightMargin: 10
leftMargin: (textInputField === "") ? 18 : 12
verticalCenter: parent.verticalCenter
}
}
and Cursor image as
Image
{
id: img_cursor
x: (textInputField !== "") ?
(text_input.x + text_input.contentWidth)) : 12
anchors.verticalCenter: parent.verticalCenter
source: "text_cursor.png"
}
Now if textInputField contains Arabic text, TextItem is auto change the orientation from right to left. and english it is changing to start from Left.
Text appending coming in :
Arabic: Left <--Right
English: Left --> Right
But for Cursor position, how i can make the logic to auto detect and change the x position of the cursor based on the text_input orientation direction (Arabic and English).
Arabic isn't always RtoL. Numbers, for example, are written LtoR (just like in English). Also, foreign words would be written LtoR. Conversely, if you add an Arabic word in an English text, text direction will change somewhere. Might be the middle of the line, might be at either end.
That's why a simple trick like calling QFontMetrics.width() will only work for simple cases.
Try QTextLayout instead. QLineEdit uses this code in it's control to figure out the X position of the cursor:
qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
I created a function to check the alignment of the text. so on arabic change , the Text orientation will be modified automatically.
function isArabicAlignment() {
if(text_input.horizontalAlignment === Text.AlignRight)
return true;
else
return false;
}
So on Text input modifies , i will check the condition and update the cursor position.
x: (textInputField !== "" && isArabicAlignment()) ?
(text_input.x + text_input.contentWidth)) : //Changing Cursor in reverse.
I would like to use font awesome font in my QML app. But it doesn't work very well.
First I use this method : https://github.com/QMLCommunity/font-awesome-qml
But I got only two icons working, see the capture of my app.
Only the laptop and battery icons are displayed. The others (one top left, and others on each tab) got kanjis or other symbols.
After I also tried that solution : How to use Font Awesome in QML
on the top left icon, whithout success.
Here the code of the notification bar :
RowLayout {
anchors.fill: parent
Label {
font.pointSize: 10
font.family: "fa-solid-900"
text: "\uf071" + " Message"
}
Item {
Layout.fillWidth: true
}
Label {
font.pointSize: 10
font.family: awesome.family
text: awesome.loaded ? awesome.icons.fa_laptop : "x"
Layout.alignment: Qt.AlignRight
}
Label {
font.pointSize: 10
font.family: awesome.family
text: awesome.loaded ? awesome.icons.fa_battery_full + " 100 %" : "x"
Layout.alignment: Qt.AlignRight
}
}
PS: I used the 2nd link solution for the first icon, but the result is exactly the same with the first solution.
And the tab bar:
footer: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
Material.theme: Material.Dark
FontAwesome {
id: awesome
resource: "qrc:///controls/fa-solid-900.ttf"
}
TabButton {
font.pointSize: 10
font.family: awesome.family
text: (awesome.loaded ? awesome.icons.fa_star : "x") + " " + "Général"
}
TabButton {
font.pointSize: 10
font.family: awesome.family
text: (awesome.loaded ? awesome.icons.fa_cogs : "x") + " " + "Test"
}
TabButton {
font.pointSize: 10
font.family: awesome.family
text: (awesome.loaded ? awesome.icons.fa_trophy : "x") + " " + "Match"
}
}
How can I display the right icons each time?
Thanks in advance!
I recently ran into the same issues and documented my approach in a blog post.
Basically, my issue was that starting with version 5, Font Awesome provides some of the icons in one font file with "regular" weight and one in a file with "solid" weight classes. However, when loading, both will register with a font name of "Font Awesome 5 Free" (assuming the free version is used).
I would have expected that it is possible to switch between the regular and solid icon sets by setting e.g. the bold property of a font in QML:
import QtQuick 2.0
Item {
width: 100
height: 100
FontLoader {
id: faRegular
source: "./fa-regular-400.ttf"
}
FontLoader {
id: faSolid
source: "./fa-solid-900.ttf"
}
Column {
width: parent.width
Text {
font.family: "Font Awesome 5 Free"
font.bold: true // use "solid" variant
text: "\uf073" // fa-calendar-alt
}
Text {
font.family: "Font Awesome 5 Free"
font.bold: false // use "regular" variant
text: "\uf073" // fa-calendar-alt
}
}
}
Unfortunately, this did not work for me, as Qt merges both fonts and only either the regular or the solid variant was used (which causes some icons from not being rendered at all, especially if you use the regular variant which contains much less icons at least in the free version of the font).
My "solution" was to edit the solid font file (e.g. using FontForge) and change the font name to e.g. "Font Awesome 5 Free Solid". With this, I was able to load both variants of the font at the same time and switch between the two by using their font name like this:
import QtQuick 2.0
Item {
width: 100
height: 100
FontLoader {
id: faRegular
source: "./fa-regular-400.ttf"
}
FontLoader {
id: faSolid
source: "./fa-solid-900.ttf"
}
Column {
width: parent.width
Text {
font.family: faSolid.name // use solid variant
text: "\uf073" // fa-calendar-alt
}
Text {
font.family: faRegular.name // use regular variant
text: "\uf073" // fa-calendar-alt
}
}
}
This is probably due to font merging when some characters cannot be resolved. You can try to load FontAwesome from C++ side
Loading the font with a QFontDatabase
int fontId = QFontDatabase::addApplicationFont(QStringLiteral("/path/to/font-awesome.ttf");
Disabling merging on a new font
QFont font("fa-solid-900"); // You can also use the fontId to get family name here
font.setStyleStrategy(QFont::NoFontMerging);
Exposing the font to QML with a QFont Q_PROPERTY or directly in the context
Q_PROPERTY(QFont fontAwesome READ fontAwesome CONSTANT)
This is discussed in the Qt mailing list here
I'd like to reduce the font size in case user types a long text in a TextField. Is there a way to know how wide the current text is rendered?
As far as I know, it is not possible to do directly. You could, however, cheat by using an invisible item that contains the properties you need:
Text {
id: hiddenText
anchors.fill: tf
text: tf.text
font.pixelSize: tf.font.pixelSize
visible: false
}
TextField {
id: tf
width: 100
height: 60
font.pixelSize: 25
onTextChanged: {
while ((hiddenText.contentWidth > hiddenText.width) || (hiddenText.contentHeight > hiddenText.height)) {
font.pixelSize -= 1
}
}
}
You would have to do the same for scaling up the text, in case the user erases some input. The Text component does not contain borders, so you have to decrease it's width by a few pixels to make it the same size as the TextField as well.
Also, check out TextArea or TextInput. They may fit your need.