Abhishek Agarwal
Abhishek Agarwal

Reputation: 1248

Add background and font colour to a button with material design

I am trying to design a login form with a material design on Qt which should look something like this:

enter image description here

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:

enter image description here

Upvotes: 2

Views: 5652

Answers (3)

GrecKo
GrecKo

Reputation: 7170

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.

Upvotes: 3

jpnurmi
jpnurmi

Reputation: 5836

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.

Upvotes: 2

derM
derM

Reputation: 13701

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

  1. Be cautious to not override states
  2. 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
    }
}

Upvotes: 2

Related Questions