Search code examples
pythonpyqtqmlpyqt5qtquickcontrols2

PyQt QML Material Design button background won't change


I'm new to QML and I'm trying to change the background color of a button but nothing seems to work. Here's the python code: import sys

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QUrl
from PyQt5.QtQuick import QQuickView


if __name__ == "__main__":

    app = QApplication(sys.argv)

    view = QQuickView()
    view.setSource(QUrl('basic.qml'))
    view.show()

    sys.exit(app.exec_())

And the basic.qml:

import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import QtQuick.Controls.Material 2.3

Rectangle {
    width:600;height:150;
    color: Material.color(Material.Red)
    Button {
        text: qsTr("Button")
        highlighted: true
        Material.background: Material.Teal
    }
}

Here is how it looks, the button isn't 'Material.Teal' and no matter what color I try it still doesn't work. I've tried it with Pane and other elements but still nothing. enter image description here

Here's where I got the code: http://doc.qt.io/qt-5/qtquickcontrols2-material.html#material-primary-attached-prop

I've tried it with other styles/methods like pallete (orFusion): https://doc.qt.io/qt-5.10/qml-qtquick-controls2-control.html#palette-prop

Page {
    palette.text: "red"

    Column {
        Label {
            text: qsTr("This will use red color...")
        }

        Switch {
            text: qsTr("... and so will this")
        }
    }
}

enter image description here


Solution

  • In your case there are 2 possible solutions:


    1. If you want to use Material.background you must establish that the style you are going to use is Material, and to do so you can choose one of the following options:

    option 1: add the style through sys.argv:

    import sys
    
    from PyQt5.QtGui import QGuiApplication
    from PyQt5.QtCore import QUrl
    from PyQt5.QtQuick import QQuickView
    
    
    if __name__ == "__main__":
        sys.argv += ['--style', 'material']
        app = QGuiApplication(sys.argv)
    
        view = QQuickView()
        view.setSource(QUrl('basic.qml'))
        view.show()
    
        sys.exit(app.exec_())
    

    option 2: add the style through os.environ():

    import os
    import sys
    
    from PyQt5.QtGui import QGuiApplication
    from PyQt5.QtCore import QUrl
    from PyQt5.QtQuick import QQuickView
    
    
    if __name__ == "__main__":
        app = QGuiApplication(sys.argv)
        os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
    
        view = QQuickView()
        view.setSource(QUrl('basic.qml'))
        view.show()
    
        sys.exit(app.exec_())
    

    option 3: create a qtquickcontrols2.conf file and load it into the application using a qresource:

    qtquickcontrols2.conf

    ; This file can be edited to change the style of the application
    ; See Styling Qt Quick Controls 2 in the documentation for details:
    ; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html
    
    [Controls]
    Style=Material
    

    then a resource.qrc is created:

    resource.qrc:

    <RCC>
        <qresource prefix="/">
            <file>qtquickcontrols2.conf</file>
        </qresource>
    </RCC>
    

    Then you must convert the .qrc to .py:

    pyrcc5 resource.qrc -o resource_rc.py
    

    and at the end the resource_rc.py file is imported into the main.py

    main.py:

    from PyQt5.QtGui import QGuiApplication
    from PyQt5.QtCore import QUrl
    from PyQt5.QtQuick import QQuickView
    
    import sys
    import resource_rc
    
    if __name__ == "__main__":
        app = QGuiApplication(sys.argv)
        view = QQuickView()
    
        view.setSource(QUrl('basic.qml'))
        view.show()
        sys.exit(app.exec_())
    

    1. or not use the Material style, and only use their colors through the use of palette:

    import QtQuick 2.0
    import QtQuick.Controls 2.3
    import QtQuick.Controls.Material 2.3
    
    Rectangle {
        width:600;height:150;
        color: Material.color(Material.Red)
        Button {
            text: qsTr("Button")
            highlighted: true
            palette.dark: Material.color(Material.Teal)
        }
    }