How can the font size of the text in a Button control be set in QML? The designer has not option, and 'font' is not a valid property of Button.
Button {
id: cmdQuit
text: qsTr("Quit")
width: 64
height: 32
}
You set the Button's style property:
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Rectangle {
id: container
width: 800
height: 800
Button {
id: cmdQuit
text: qsTr("Quit")
width: 64
height: 32
style: ButtonStyle {
label: Text {
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Helvetica"
font.pointSize: 20
color: "blue"
text: control.text
}
}
}
}
For QtQuick 2, you have to use the contentItem property as shown here: https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-button
import QtQuick 2.12
import QtQuick.Controls 2.12
Button {
id: control
text: qsTr("Button")
contentItem: Text {
text: control.text
font.pointSize: 20
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
}
This is an old question, but since it comes first in search engines I'm providing an update on the situation.
For QtQuick2, unlike what Chris said, you don't need to use the contentItem property anymore. You can access the font property directly from Button.
Example:
Button {
id: btn
text: "Test"
font.pixelSize: 18
}
Related
The short version
I'd like to horizontally and/or vertically center groups of QML widgets without being forced to align them in a structured layout.
The long version
I made the following design:
My QML code so far is as follows. (I know the hardcoded X/Y coordinates are sloppy, it's just a mockup.)
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Shapes 1.11
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.0
Window {
id: window
visible: true
width: 640
height: 480
color: "#f0eded"
title: qsTr("Hello World")
Image {
id: image
x: 215
y: 96
sourceSize.height: 210
sourceSize.width: 210
source: "lock.svg"
}
Text {
id: element
y: 364
anchors.horizontalCenter: parent.horizontalCenter
color: "#646464"
text: qsTr("Unlock your rclone configuration to continue.")
anchors.horizontalCenterOffset: 0
styleColor: "#00000000"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 12
}
TextField {
id: txtPassword
x: 193
y: 312
focus: true
font.pointSize: 22
horizontalAlignment: Text.AlignHCenter
echoMode: TextInput.Password
}
Button {
id: btnContinue
x: 399
y: 312
width: txtPassword.height
height: txtPassword.height
text: qsTr("»")
background: Rectangle {
border.color: btnContinueMouse.containsMouse ? "#cdcdcd" : "#ccc"
color: btnContinueMouse.containsMouse ? "#eee" : "#ddd"
}
MouseArea {
id: btnContinueMouse
anchors.fill: parent
hoverEnabled: true
}
}
}
What I'd like to do is to horizontally and vertically center this group of widgets so that its alignment still makes sense if a user increases the size of the window. I know I can put widgets into a row/column/grid layout for such purposes, but then I lose a lot of control over the space between the widgets.
What approach would you recommend to turn this mockup into clean QML code while staying true to the original design?
Two ways:
Wrap it in an Item, then
Use anchors to position your content relative to the screen like this:
Item {
anchors.fill: parent
Image {
id: image
anchors.left: parent.left
anchors.right: parent.right
sourceSize.height: 210
sourceSize.width: 210
source: "lock.svg"
}
Text {
id: element
anchors.top: txtPassword.bottom
anchors.left: txtPassword.left
anchors.right: btnContinue.right
color: "#646464"
text: qsTr("Unlock your rclone configuration to continue.")
styleColor: "#00000000"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 12
}
OR
Create separate components out of the different parts then place them as a whole into a layout. Do this by moving your elements into a separate file then referencing that file using its name:
example:
LockElement { anchors.centerIn: parent }
will load LockElement.qml which will have your Item, Image, TextBox etc all in one file.
This will make the coordinates relative to their own coordinate space.
LockElement.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Shapes 1.11
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.0
Item {
width: 640
height: 480
Image {
id: image
x: 215
y: 96
sourceSize.height: 210
sourceSize.width: 210
source: "lock.svg"
}
Text {
id: element
y: 364
anchors.horizontalCenter: parent.horizontalCenter
color: "#646464"
text: qsTr("Unlock your rclone configuration to continue.")
anchors.horizontalCenterOffset: 0
styleColor: "#00000000"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 12
}
TextField {
id: txtPassword
x: 193
y: 312
focus: true
font.pointSize: 22
horizontalAlignment: Text.AlignHCenter
echoMode: TextInput.Password
}
Button {
id: btnContinue
x: 399
y: 312
width: txtPassword.height
height: txtPassword.height
text: qsTr("»")
background: Rectangle {
border.color: btnContinueMouse.containsMouse ? "#cdcdcd" : "#ccc"
color: btnContinueMouse.containsMouse ? "#eee" : "#ddd"
}
MouseArea {
id: btnContinueMouse
anchors.fill: parent
hoverEnabled: true
}
}
}
// etc..
I am new to QML development. I would like to customize the QML button for our requirement. In some QML sample projects, the customization is done as Button.QML by
drawing a rectangle and implementing mouse area onclick() events. example,
import QtQuick 2.5
Rectangle {
id: button
signal clicked
property alias text: text.text
border.width: 1
border.color: "white"
property real textHeight: height - 2
property real fontHeight: 0.3
property bool pressed: mouse.pressed
property real implicitMargin: (width - text.implicitWidth) / 2
Text {
id: text
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: parent.textHeight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: height * fontHeight
color: "#1b1c1d"
font.family: "Open Sans Regular"
}
MouseArea {
id: mouse
anchors.fill: parent
onClicked: button.clicked()
}
}
This code is works for me. But I saw another QT example as
import QtQuick 2.12
import QtQuick.Controls 2.0
Button {
id: controlBt
text: qsTr("Test")
font.pixelSize: 32
contentItem: Text {
text: controlBt.text
font: controlBt.font
opacity: enabled ? 1.0 : 0.3
color: controlBt.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 550
implicitHeight: 66
opacity: enabled ? 1 : 0.3
border.color: controlBt.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
}
But by using this code for customization, Focus and key events are not working for the button.
Could anyone provide me the best and correct way to customize a QML button.
Thanks
I have used the following code for the customization
UiButton.qml
import QtQuick 2.12
import QtQuick.Controls 2.0
Button {
id: controlBt
text: qsTr("Test")
font.pixelSize: 32
contentItem: Text {
text: controlBt.text
font: controlBt.font
opacity: enabled ? 1.0 : 0.3
color: controlBt.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 550
implicitHeight: 66
opacity: enabled ? 1 : 0.3
border.color: controlBt.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
}
In the test.qml i have used the above button as
UiButton
{
id: idTestButton
x: 250
y: 512
focus: true
visible: false
KeyNavigation.down:
{
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: down")
}
Keys.onLeftPressed:
{
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: onLeftPressed")
}
onClicked: {
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: onClicked")
}
}
in the application, I have a listView and on pressing down from the last item of listView, i need to set focus on the test button.
on listView Keys.onDownPressed:
Keys.onDownPressed:
{
// on pressing down from last item, I set focus to button as
idTestButton.forceActiveFocus()
}
on using forceActiveFocus(), everything worked for me. Thank you all for your support
Thanks you
I've got two Labels A and B in a row which need to be anchored together such that there is no spacing between them. A is not allowed to be larger than it's content, because B is like a detail label. It would be weird to see Google Chrome_____(the current browser). You'll want Google Chrome (the current browser)____ in this case.
Both have a common parent that they can fill up. Content-wise both A and B can be the larger of the two. The whole thing should be left aligned such that A is anchored to the parent's left and B.left == A.right.
When there is not enough space, both items should shrink and elide until they fit the parent, eg Google Chr..(The current br...
This last part is what I could not figure out how to do.
I'm using 2 labels instead of 1 because they need their own elision and their own styling.
My current solution will simply elide B, not shrink A at all.
RowLayout
{
spacing: 0
anchors.left: parent.left
anchors.right: customisedSettings.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
Label
{
id: textLabelA
text: qualityName()
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
Layout.margins: 0
height: contentHeight
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
function qualityName() {
[...]
}
}
Label
{
id: textLabelDetail
text: activeQualityDetailText()
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_detail")
anchors.verticalCenter: textLabelA.verticalCenter
Layout.margins: 0
Layout.fillWidth: true
height: contentHeight
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
function activeQualityDetailText()
{
[..]
}
}
}
You can do that by putting them in a RowLayout and setting Layout.fillWidth: true on both of them so they both shrink.
To ensure that the first Label isn't larger than needed, set Layout.maximumWidth: implicitWidth.
This gives us :
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Window 2.3
import QtQuick.Layouts 1.2
Window {
visible: true
width: 600
height: 400
RowLayout {
anchors.fill: parent
Label {
text: "Google Chrome"
Layout.fillWidth: true
Layout.maximumWidth: implicitWidth
elide: Text.ElideRight
}
Label {
text: "(the current browser)"
color: "darkgray"
Layout.fillWidth: true
elide: Text.ElideRight
}
}
}
Trying different code combinations and partially solving my problem I came across a behavior that I can not quite explain. So to the point, When I create a simple TextArea without Scrollview it looks like this:
RowLayout {
id: rowLayout
Rectangle{
height: 50
width: 295
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
anchors.fill: parent
}
}
Text area creates a default background. And now I want to do TextArea with ScrollView ALSO with the default TextArea background but it comes out something like that :
RowLayout {
id: rowLayout
Rectangle{
height: 50
width: 295
ScrollView {
id: scrollView1
anchors.fill: parent
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
}
}
}
The only chance to set the default TextArea background is set implicitHeight,implicitWidth but then after entering the text into a TextArea until the scrollbar appears, the background extends over the entire length by going behind the other components like this :
RowLayout {
id: rowLayout
Rectangle{
//color: "#00000000"
height: 50
width: 295
ScrollView {
id: scrollView1
anchors.fill: parent
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
implicitHeight: 50
implicitWidth: 295
}
}
}
So the only thing I want is a scrollable textarea but with this black default background and NOT my background which I can do with rectangle.
Can anyone take a look?
Thank you :)
I tried do my best. Check the example below, hope it will help =)
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 400
height: 400
RowLayout {
width: 295
height: 50
anchors.centerIn: parent
ScrollView {
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle { color: "black" }
TextArea {
id: messageField
placeholderText: qsTr("message...")
color: "white"
wrapMode: TextArea.WrapAnywhere
}
}
}
}
Result:
I am referring to https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-spinbox and copy pasted the same code, But i am getting following errors:
ReferenceError: down is not defined and
ReferenceError: up is not defined.
Code:
import QtQuick 2.6
import QtQuick.Controls 2.1
SpinBox {
id: control
value: 50
editable: true
contentItem: TextInput {
z: 2
text: control.textFromValue(control.value, control.locale)
font: control.font
color: "#21be2b"
selectionColor: "#21be2b"
selectedTextColor: "#ffffff"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
down.indicator: Rectangle {
x: control.mirrored ? parent.width - width : 0
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: down.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "-"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
background: Rectangle {
implicitWidth: 140
border.color: "#bdbebf"
}
}
Should i include any additional imports ?
No, you don't need to include any additional imports. It is just, that the example uses bad practice and here you see why:
This is the (reduced to modifying only the up.indicator) code of the example:
import QtQuick 2.6
import QtQuick.Controls 2.0
SpinBox {
id: control
value: 50
editable: true
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6" // <---*
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
Here we have the SpinBox as the root element of the file.
Now lets talk about name resolution.
The line in question is marked with a // <---*
control: up.pressed ? "..." : "..."
Where does up come from? At first it will look in the object, where it is used - the Rectangle. The Rectangle has no up-property, so it will continue and looking in the root node of the file, which is the SpinBox - this has a up-property, which also has a value for pressed.
The situation looks different, when we try to use it (the wrong way). Let's add a ApplicationWindow:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 800
height: 600
visible: true
SpinBox {
id: control
value: 50
editable: true
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
Same line - will try to look up up in the Rectangle, fails and continues to the files root node, which is now an ApplicationWindow. Here it fails again. As the ApplicationWindow is not used in another file, where another files root node might exist, the search will end and finally fail.
What went wrong? The writer of the example missed the to apply the good practice to always use fully qualified identifiers: id.property.... as he did for example to define the x-value of the Rectangle.
Changing the line:
color: up.pressed ? [...]
to:
color: control.up.pressed ? [...]
will solve the problem, as we now explicitly declare where to look for the property up.
Important Lesson
Names are not resolved by going from child to parent, but always from child to the files root node and so on, until it can't go on
Always identify the object either explicitly by parent (but be aware, that you might not know what exactly the parent is. So ideally only for anchors and position) or by the objects's id