QML FontLoader.name confusion - qt

I downloaded from Google Fonts two .ttf files on my project folder:
Montserrat-ExtraLight.ttf
Montserrat-Black.ttf
I set propperly the .qrc file in order to contain both of them.
Suppose I have the next .qml file:
import QtQuick 2.7
import QtQuick.Layouts 1.2
import QtQuick.Controls.Universal 2.0
Rectangle{
id: rectangle
height: 500
width: 700
Column{
FontLoader { id: myCustomFont1; source: "../Fonts/Montserrat/Montserrat-ExtraLight.ttf" }
FontLoader { id: myCustomFont2; source: "../Fonts/Montserrat/Montserrat-Black.ttf" }
Text{
...
text: "Qt for python"
font.family: myCustomFont1.name
...
}
Text{
...
text: "Qt for c++"
font.family: myCustomFont2.name
...
}
}
}
The problem is that the myCustomFont1.name and the myCustomFont2.name are the same, namely "Montserrat" and I don't have any solution to make distinction between them.
Therefore even if I specified the correct FontLoader-s id-s, the second text will have the same font.family like the first text.
Could be possible to solve this problem somehow?

This is not an ideal solution, but a workaround that should work. There's an open-source font editor called FontForge that you can use to change the names that Qt reads. Open the font files in question and then open the menu Element->Font Info. That opens a dialog with multiple tabs on the left. The first tab should be PS Names. This should list several fields including Fontname and Family Name. You should be able to edit those to whatever you want. Then close that dialog and use File->Generate Fonts to regenerate the .ttf files.

This is perplexing and a common source of frustration. It turns out that the name property actually specifies the family, which as you've discovered, is the same for these font files.
What distinguishes them is actually the styleName.
Try opening the font file in a font viewer like "Font Book" or "FontForge" to get the exact styleName - you'll need to specify it with a string.
Then specify the additional property:
Text{
...
text: "Qt for python"
font.family: myCustomFont1.name //or myCustomFont2.name, it doesn't matter.
font.styleName: "Extra Light"
...
}
Text{
...
text: "Qt for c++"
font.family: myCustomFont2.name
font.styleName: "Black"
...
}
I've found styleName far more predictable than combinations of weight or style or bold. And that way you can work with fonts that follow the canonical naming conventions rather than hacking their Family Name to suit QML.

Related

How to change qml's SystemPalette globally in linux

I'm using systemPalette (Qt5.15) in several qml-based applications in Linux, I need one of these applications to change systemPalette of qml system-wide (globally) so that other applications can detect this change at runtime.
what I need is similar to what happens in KDE, for example, I have the following qml code:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
SystemPalette {
id: palette
colorGroup: SystemPalette.Active
}
Rectangle{
anchors.centerIn: parent
width: 200
height: width
color: palette.base
}
}
when I run the above code in my KDE plasma, if I change the system's theme from breeze to breeze-dark, the rectangle's color will change at runtime, I can even select a custom color in
Appearance->globalTheme->colors.
In my case, regardless of Linux's distro, my application needs to change systemPalette globally and set its custom values for colors, how can I do that? where does qt read those color values from? (for systemPallete)
Thanks.
P.S: I can create my own style/plugin for qt and set different colors in my custom style, but still I have no idea how to change OS style globally so that all applications can detect this at runtime.

Paragraph indent in qml

I need a way a to adopt property text-indent in my qml code. QML Docs says it's supported, but didn't explain how to use it. I'm trying to run something like that (I tried more variants but failed):
Text{
width: parent.width
wrapMode: Text.WordWrap
textFormat: Text.StyledText
text: "<text-indent='50px'>Hellow world"
}
But it doesn't work. Qml sees text-indent in code (or it just see "<>") and doesn't show it in the text label, but still didn't activate it.
Maybe this is kinda extra but the same question I can ask about all of tags which I can see in the documentation.
you should change your text format to Text.RichText and also use HTML tag and correct CSS style and CSS rules.
Please See textFormat Doc
Text.RichText supports a larger subset of HTML 4, as described on the Supported HTML Subset page
Text{
width: parent.width
wrapMode: Text.WordWrap
textFormat: Text.RichText
text:"<p style=\"text-indent:50px;\">Hello World</p>"
}
The output:

Custom checkbox shows original checkbox in QML and QtQuick

I'm using the custom checkbox that was used as an example in the QT Documentation posted with QtQuick 2.15 with Qt 6.2.1:
CheckBox {
id: control
text: qsTr("CheckBox")
checked: true
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 3
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 2
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
}
However, this example does not work. This is what I am seeing:
Checked
Checked and Hovered
Unchecked and Hovered
None
I am wondering if there is any fix to this. I have seen others with the same problem and no solution
This is the same issue as QTBUG-95589: native styles shouldn't be customised. The Customization Reference says:
Note: The macOS and Windows styles are not suitable for customizing. It is instead recommended to always base a customized control on top of a single style that is available on all platforms, e.g Basic Style, Fusion Style, Imagine Style, Material Style, Universal Style. By doing so, you are guaranteed that it will always look the same, regardless of which style the application is run with. For example:
There are two solutions:
Use a different style. I've linked to the run-time style selection documentation because it's the easiest and most common way of selecting a style, but you can also use compile-time style selection if your application only uses one style.
Style the control completely from scratch. Any time you use a type from QtQuick.Templates, no styling is applied, so you don't need to worry about which style is in use.
In Qt 6, the native styles were added, and at the same time a change was made to make the default style (i.e. the style that is used if none is specified) a platform-specific one. So if you don't specify a style on e.g. Windows, you'll get the native Windows style. Unfortunately this causes issues when customising controls, because the native styles are not designed to be customised.
Eventually the goal is to have Qt Creator warn the user when it detects that they are customising a native style.

Setting the Style in qml Qt

I want to set the Style for my elements in qml. For that, I want to use a style like Material Style. Using the example which can be found under:
https://doc.qt.io/qt-5/qtquickcontrols2-material.html
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
ApplicationWindow {
visible: true
Material.theme: Material.Dark
Material.accent: Material.Purple
Column {
anchors.centerIn: parent
RadioButton { text: qsTr("Small") }
RadioButton { text: qsTr("Medium"); checked: true }
RadioButton { text: qsTr("Large") }
}
}
Gives me the result seen in the image I attached.
No matter which Style I use, nothing changes.
I am currently using the newest free Qt version under a Windows 10 Os.
Can anyone help me?
And is it possible to globally overwrite a Style and make an own Style, simply in QML.
As the docs points out:
To run an application with the Material style, see Using Styles in Qt Quick Controls.
There are several ways to set the style in Qt Quick Controls 2:
Using QQuickStyle in C++:
add QT += quickcontrols2 in your .pro and use #include <QQuickStyle> and QQuickStyle::setStyle("Material"); in main.cpp
Command line argument:
You can run from the console/CMD by adding the argument: ./your_executable -style material.
If you use Qt Creator you can go to Projects-> Build & Run-> Run and in Command line arguments add: -style material.
Environment variable:
You can run from the console/CMD: QT_QUICK_CONTROLS_STYLE=material ./your_executable
If you are using Qt Creator you can add it in the section Projects-> Build & Run-> Run-> Run Environment.
or add qputenv("QT_QUICK_CONTROLS_STYLE", "material"); in main.cpp.
Configuration file:
The qtquickcontrols2.conf file must be created:
[Controls]
Style=Material
and must be in a qresource:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>qtquickcontrols2.conf</file>
</qresource>
</RCC>
You have to set the style from C++ as well. See this Qt documentation.
So in you main add QQuickStyle::setStyle("Material");

How to create a custom grouping of properties and apply them to different controls?

I have a window with Buttons, TextFields, Labels etc. These all share common properties like font family, color, size etc. What I would like to be able to do is to define a grouping of these properties (called, say, textStyles.MainTitle or textStyles.DescriptiveText etc.) that would include a font family, size and weight, height and color. And then in the QML file I would write something like:
myCustomProperty: textStyles.MainTitle
and this would apply those values to the control. How can I do this?
QML controls are styled by implementing their respective styles, for example for Button you have to implement a ButtonStyle.
As for the actual "grouping" you can just use a QtObject
property QtObject textStyles : QtObject {
property FontLoader mainTitle : FontLoader {...}
....
}
You can also extend styled components as dedicated types:
// StyledText.qml
Text {
font.family: someFont
font.pixelSize: fontSize
color: someColor
font.italic: true
font.letterSpacing: -1
...
}
And then use that by just StyledText {} instead of repeatedly styling regular Text elements.
Where / in what file do I place the QtObject snippet? I don't understand what // StyledText.qml is, or what a FontLoader is.
If you want it to be available in your entire application, you can put it as a property of your root object in main.qml, thanks to dynamic scoping textStyles will resolve from every other file in your project. You can put entire component styles in it as well and share in the project.
StyledText.qml is just an extra qml file you add to your project, you can being with just implementing its body in an existing qml file, then rightclick on Text and select refactoring -> move component into separate file.
A FontLoader is just a regular QML component, you can use it to load specific fonts and use as a font source for text. You don't have to use that, you can use font families from your system fonts as well. The font loader is useful for fonts you bundle with your application.

Resources