I have a custom QML Buton as shown bellow.
import QtQuick 2.15
import QtQuick.Controls 2.15
Button{
id: dashId
width: 155
height: 40
implicitWidth: 155
implicitHeight: 40
text: 'hello'
flat: true
property color colorNormal: '#353535'
property color colorHovered: '#04b9b9'
property color colorClicked: '#4d4f50'
background: Rectangle{
id: bgColor
radius: 10
color: internal.hoverColor
}
contentItem: Item {
id: buttonItem
visible: true
Text {
id: buttonText
text: dashId.text
anchors.centerIn: parent
color: 'white'
}
}
QtObject{
id: internal
property var hoverColor: if(dashId.down){
dashId.down ? colorClicked : colorNormal
}else{
dashId.hovered ? colorHovered : colorNormal
}
}
}
when hovered, its still have its default hover color on top of custom hover color instead of just custom color.
Am using Qt6 and QtQuick 1.14.1 on Windows 10.
I found the issue.
I had to set highlighted: true and flat: true inside my button.
I had a similar issue. On macOS and Linux, all buttons rendered as expected but on Windows, there was a transition to the wanted hover color and after that the button faded to white.
The issue was solved with:
flat:true
Related
I just want to change the background color of QML buttons but it seems there are no simple way. Can you tell me a simple way to change the background color of QML Button? Thanks!
Update: a code I have searched:
import QtQuick 2.6
import QtQuick.Controls 2.1
Button {
id: control
text: qsTr("Button")
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
color: "black" // I update background color by this
}
}
Works with QT Quick 2:
Button {
id: button
text: qsTr("Button text")
background: Rectangle {
color: parent.down ? "#bbbbbb" :
(parent.hovered ? "#d6d6d6" : "#f6f6f6")
}
}
The above code change the button color when the button is down or hovered. It is also possible to add a border or other customizations.
The common way for QtQuick.Controls 2 is to redefine default Control visual properties to customize a Control. The disadvantage of this approach as I said above is that you cannot change, for example, just background color. Overriding Control.background forcing you to redefine all the element, including border, colors, animation etc.
Looking at the Button's source we can see that defines default Control.background property based on a Control.palette. Using this property we can override the Control properties:
For example:
Button {
text: "Test button"
palette {
button: "green"
}
}
But you should understand that internal source could be changed in the future. Also you have to imagine for yourself what palette properties is used by specified Control.
In the example above I redefine palette for specified Control. But you can redefine the palette globally, either be setting the color in qtquickcontrols2.conf or by setting custom palette in C++ - QGuiApplication::setPalette().
You can do this simply with Material.background of Button:
Button
{
id: button
Material.background:Material.Red
}
The issue seems so trivial that I almost believe it's a bug in Qt itself:
import QtQuick.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
Window {
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
color: "white"
Layout.columnSpan: 2
Layout.fillHeight: true
Layout.fillWidth: true
radius: 5
width: 640/2
height: 480/2
TextArea {
id: txtMemo
anchors.fill: parent
anchors.margins: 5
textColor: "black"
wrapMode: TextEdit.Wrap
readOnly: false
}
}
Button {
x: 0
y: 480/2
width: 640/2
height: 480/2
onClicked: {
//Qt.inputMethod.hide()
txtMemo.visible = false
}
}
}
You need to run this on an Android device to see the bug:
Type something in to the text area so the cursor and virtual keyboard appears.
When you click the button, the cursor & keyboard stay on screen. No idea why, perhaps a feature.
Anyways, that's not the main issue. When I uncomment Qt.inputMethod.hide() and trying to reproduce, an interesting thing happens:
if the keyboard is visible, both the cursor and keyboard disappear - awesome, exactly what I want
however if the keyboard isn't visible (closed by the arrow on the bottom during typing) and the cursor is, the cursor won't disappear at all:
(apologies for the picture quality)
So how do I get rid of the cursor? Tested on Qt 5.9.6 on Android (seems unrelated on Android version, happens on the latest version as well).
I want to create a custom dialog in qml without the ok button.
this is my code :
Dialog {
id: DialogId
title: appName
}
when the dialog is opened there is an Ok button.
I'm using QtQuick.Dialogs 1.2
The property standardButtons controls wich buttons are in your dialog.
The default value is StandardButton.Ok
If you don't whant any button you need to re-implement contentItem
For instance:
contentItem: Rectangle {
color: "lightskyblue"
implicitWidth: 400
implicitHeight: 100
Text {
text: "Hello blue sky!"
color: "navy"
anchors.centerIn: parent
}
}
I am trying to design a login form with a material design on Qt which should look something like this:
However I can't figure out how to add colour to the button in QML and change the font colour of the button text. This is what I have got so far:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Item {
property alias login: login
Pane {
id: pane
x: 144
y: 117
width: 353
height: 246
clip: false
font.strikeout: false
background: Rectangle {
color: "#ffffff"
}
ColumnLayout {
id: columnLayout
x: 139
y: -158
anchors.fill: parent
TextField {
id: username
Layout.fillWidth: true
placeholderText: qsTr("Username")
}
TextField {
id: password
Layout.fillWidth: true
placeholderText: qsTr("Password")
}
Button {
id: login
text: qsTr("Login")
spacing: -2
font.capitalization: Font.MixedCase
Layout.fillWidth: true
highlighted: false
// background: Rectangle {
// implicitWidth: 100
// implicitHeight: 40
// color: button.down ? "#d6d6d6" : "#f6f6f6"
// border.color: "#26282a"
// border.width: 1
// radius: 4
// }
}
}
}
}
As you can see (in the commented code) I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
For reference here is the output of my code:
In order to theme a Material controls, you have to use the Material attached properties
In your case you want to use Material.background :
import QtQuick.Controls.Material 2.2
// ...
Button {
id: login
text: qsTr("Login")
Layout.fillWidth: true
Material.background: Material.Indigo
Material.foreground: "white"
}
Note that buttons should have upercased text, according to the material guidelines.
If you want to have a design that complies with the Google Materials design guidelines, the easiest way, is to use
QtQuick.Controls.Materials
To use them, it is sufficent to use any of the methods described here to activate them in your application. To try it out, I'd reccomend the command line argument. Just start your application with
-style material
If you want to have it fixed in your code, put it in the main.cpp:
QQuickStyle::setStyle("Material");
Note that the -style options is the very same option defined here for widgets and desktop os styles. Despite this quick styles and widget styles are totally different things and you cannot apply the former to the latter and vice versa. Widget
If now you already use the Material-style, but are not contempt with it and desire to change some of the definitions for selected controls, you can import
import QtQuick.Controls.Materials 2.x
where you need to adapt x to the most recent version installed. 0 is the right one for Qt5.7
Then you can alter specific aspects like
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
ApplicationWindow {
id: mainWindow
width: 800
height: 600
visible: true
Button {
id: login
text: qsTr("LOGIN")
Material.background: Material.Orange // Change the background
}
}
If you don't want to use the Material and only want to change a specific color of the Control you need to understand why it is not that easy to do, without messing it up.
I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
You can't just change the color of the background, as there is not the color. There are various colors that are applied for different states. The expression might look like this:
color: (control.down ? 'darkgrey' : 'lightgrey')
So if you change the color to orange like this:
color: 'orange'
you messed up, as now the other state is not considered anymore.
Additionally, of course, you can't change the color of the background like background.color: 'green' from the beginning, as QML does not know about the property background.color. It expects an Item there, which has no color and the Rectangle is only created later. So what you need to do is
Be cautious to not override states
Wait until the property is available
example.qml
Button {
id: login
text: qsTr("LOGIN")
Binding {
target: login
property: "background.color"
value: 'red'
when: !login.pressed // Here comes the state
}
}
You can simply highlight a Button to make the button colorize its background in a style-independent way. The Material style fills the background with the accent color and makes the text light:
Button {
text: qsTr("Login")
highlighted: true
}
A highlighted Button is by far more efficient than a customized button. Customization should be done only if necessary. It is just a visual highlight. There can be multiple highlighted buttons. Highlighting a Button does not affect focus.
I have one Checkbox with onCheckedChanged handler and what I want is, when the Checkbox is checked, dropdown a menu with several texts and text fields. I have the following code:
CheckBox {
id: box
onCheckedChanged: {
// TODO here to dropdown a menu with settings
}
}
I have texts and text fields like the following:
Component {
id: label
Text {
color: "red"
antialiasing: true
smooth: true
}
}
I'm a newbie in QML so please be patient.
You didn't really say where this menu is located, if it's floating or if it is to just appear maybe displacing other elements on the view. Anyway, to anwser your question, you can achieve what you're asking by setting the height of your 'menu' to zero then, when the CheckBox is checked, setting it to however tall you want it to be. To make the menu grow smoothing you can use a NumberAnimation.
You can change your onCheckedChanged() slot to look like this:
onCheckedChanged: {
menu.height = checked ? 100 : 0
}
and add the following, as a child of your menu element:
Behavior on height { NumberAnimation {...} }
to make the menu's height grow from 0 to 100 over a period of time to make it grow smoothly.
Another approach, which I'd prefer, is to use States with a Transition (instead of a Behavior).
Here is an example of a 'menu' which, when the CheckBox is checked, will slide out from beneath the CheckBox:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Rectangle {
id: checkboxContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 100
color: "pink"
CheckBox {
id: menuCheckBox
anchors.centerIn: parent
text: qsTr("Click Me")
}
}
Rectangle {
id: menu
anchors.top: checkboxContainer.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 0 //This is the default value when the 'default' state is active. That is whenever we're not in the "openState"
clip: true // this hurts rendering performance a bit but is required to make sure child elements don't exceed the bounderies of this object (so when height is zero you don't see the text)
color: "lightblue"
states: [
State {
name: "openState"
when: menuCheckBox.checked // This state is only active when the check box is checked. When you uncheck the check box we move to the 'default' state (which sets the menu's hight back to zero)
PropertyChanges {
target: menu
height: 100
}
}
]
transitions: Transition {
NumberAnimation {
property: "height"
duration: 350 //This means when the height property is changed it will take 350ms to move from what its at to what your changing it to (i.e. 0 to 100 or 100 to 0).
easing.type: Easing.InOutQuad
}
}
Text {
anchors.centerIn: parent
color: "red"
antialiasing: true
smooth: true
text: qsTr("HELLO")
}
}
}
I hope this answers your question.