Search code examples
qtqmlqt5qtquick2qtquickcontrols

How to change the font color of a MenuBar?


How can I change the text color of the menu items of a QML MenuBar?

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.3 as QtQuickControlStyle

ApplicationWindow {
    title: qsTr("Test")
    width: 640
    height: 480
    visible: true

    property color menuBackgroundColor: "#3C3C3C"
    property color menuBorderColor: "#282828"

    menuBar: MenuBar {

        style: QtQuickControlStyle.MenuBarStyle {
            padding {
                left: 8
                right: 8
                top: 3
                bottom: 3
            } 
            background: Rectangle {
                border.color: menuBorderColor
                color: menuBackgroundColor
            }
            // font: // how to set font color to red?
            // textColor: "red" /* does not work - results in Cannot assign to non-existent property "textColor" */
            TextField {  // does also not work
                style: TextFieldStyle {
                    textColor: "red"
                }
            }
        }
    }
}     

A similar question has been asked here but it seems not to work with menu items.


Solution

  • You have to redefine itemDelegate and itemDelegate.label for menuStyle. The former defines the style of the MenuBar text whereas the latter defines the style of menu items text.

    In the following example I defined a full style for MenuBar and Menus, not only for their text. scrollIndicator is the only missing piece here. It can be represented as a Text/Label or an Image.

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    import QtQuick.Window 2.2
    
    ApplicationWindow {
        title: qsTr("Test")
        width: 640
        height: 480
        visible: true
    
        property color menuBackgroundColor: "#3C3C3C"
        property color menuBorderColor: "#282828"
    
        menuBar: MenuBar {
    
            Menu {
                title: "File"
                MenuItem { text: "Open..." }
                MenuItem { text: "Close" }
            }
    
            Menu {
                title: "Edit"
                MenuItem { text: "Cut"; checkable: true}
                MenuItem { text: "Copy" }
                MenuItem { text: "Paste" }
                MenuSeparator {visible: true }
                Menu {
                    title: "submenu"
                }
            }
    
            style: MenuBarStyle {
    
                padding {
                    left: 8
                    right: 8
                    top: 3
                    bottom: 3
                }
    
                background: Rectangle {
                    id: rect
                    border.color: menuBorderColor
                    color: menuBackgroundColor
                }
    
                itemDelegate: Rectangle {            // the menus
                    implicitWidth: lab.contentWidth * 1.4           // adjust width the way you prefer it
                    implicitHeight: lab.contentHeight               // adjust height the way you prefer it
                    color: styleData.selected || styleData.open ? "red" : "transparent"
                    Label {
                        id: lab
                        anchors.horizontalCenter: parent.horizontalCenter
                        color: styleData.selected  || styleData.open ? "white" : "red"
                        font.wordSpacing: 10
                        text: styleData.text
                    }
                }
    
                menuStyle: MenuStyle {               // the menus items
                    id: goreStyle
    
                    frame: Rectangle {
                        color: menuBackgroundColor
                    }
    
                    itemDelegate {
                        background: Rectangle {
                            color:  styleData.selected || styleData.open ? "red" : menuBackgroundColor
                            radius: styleData.selected ? 3 : 0
                        }
    
                        label: Label {
                            color: styleData.selected ? "white" : "red"
                            text: styleData.text
                        }
    
                        submenuIndicator: Text {
                            text: "\u25ba"
                            font: goreStyle.font
                            color: styleData.selected  || styleData.open ? "white" : "red"
                            styleColor: Qt.lighter(color, 4)
                        }
    
                        shortcut: Label {
                            color: styleData.selected ? "white" : "red"
                            text: styleData.shortcut
                        }
    
                        checkmarkIndicator: CheckBox {          // not strinctly a Checkbox. A Rectangle is fine too
                            checked: styleData.checked
    
                            style: CheckBoxStyle {
    
                                indicator: Rectangle {
                                    implicitWidth: goreStyle.font.pixelSize
                                    implicitHeight: implicitWidth
                                    radius: 2
                                    color: control.checked ?  "red" : menuBackgroundColor
                                    border.color: control.activeFocus ? menuBackgroundColor : "red"
                                    border.width: 2
                                    Rectangle {
                                        visible: control.checked
                                        color: "red"
                                        border.color: menuBackgroundColor
                                        border.width: 2
                                        radius: 2
                                        anchors.fill: parent
                                    }
                                }
                                spacing: 10
                            }
                        }
                    }
    
                    // scrollIndicator:               // <--- could be an image
    
                    separator: Rectangle {
                        width: parent.width
                        implicitHeight: 2
                        color: "white"
                    }
                }
            }
        }
    }
    

    And here is the resulting MenuBar and Menus:

    enter image description here

    You can also choose to set a MenuStyle directly inside a Menu, in the style property. Something like this:

    Menu {
        title: "File"
        MenuItem { text: "Open..." }
        MenuItem { text: "Close" }
    
        style: MenuStyle {
            itemDelegate.label: Label {
            color: "blue"
            text: styleData.text
    
            // stuff above here
        }
    }
    

    In this last example only the "File" Menu items are styled with a blue color for text. One can argue how much ugly that would be, though.