Search code examples
qtqmlqgridlayoutqqmlcomponent

QML: How to select a row in GridLayout


I want when I click or hover over a row in a GridLayout to change its background. How can I do this?

I tried to create a custom row for this action, but got stuck on the fact that I would have to create several such objects for each field (ComboBox, Label, TextInput, Button).

Here is my code for the resulting row:

Rectangle {
    id: root
    width: 200
    height: 20
    color: field.activeFocus ? "#a6a6a6" : (hovered ? "#c0c0c0" : "#eaeaea")
    property bool hovered: false

    MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        onClicked: {
            field.forceActiveFocus()
        }
        onEntered: { hovered = true}
        onExited: { hovered = false}
    }

    GridLayout {
        anchors.fill: parent
        columns: 2
        Label
        {
            id: label
            Layout.row: 0
            Layout.column: 0
            text: "Unknown"
            Layout.minimumWidth: 80
            Layout.fillHeight: true
            Layout.fillWidth: true
            font.weight: field.activeFocus ? Font.Bold : Font.Normal

        }
        Label // ComboBox // TextInput // Button
        {
            id: field
            Layout.row: 0
            Layout.column: 1
            text: "Unknown"
            Layout.minimumWidth: 80
            Layout.minimumHeight: 20
            Layout.fillHeight: true
            Layout.fillWidth: true
        }
    }
}

Here is where it will be used: Used


Solution

  • Here's one potential solution to your problem.

    • Create a dummy parent Item and allow it to receive focus with focus: true
    • Also allow the dummy parent to receive to receive custom children with default property alias children: ctl.children
    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    Page {
        Column {
            spacing: 10
            Special { Label { text: "Empty" } }
            Special { Label { text: "0" } }
            Special { Label { text: "0" } }
            Special { Label { text: "0" } }
            Special { ComboBox { model: ["Empty"] } }
            Special { Button { text: "Button" } }
        }
    }
    
    // Special.qml
    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    Item {
        id: control
        width: 400
        height: 40
        focus: true
        default property alias children: ctl.children
        Rectangle {
            anchors.fill: parent
            color: control.activeFocus ? "#a6a6a6" : (mouseArea.hovered ? "#c0c0c0" : "#eaeaea")
        }
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onClicked: control.forceActiveFocus()
            property bool hovered: false
            hoverEnabled: true
            onEntered: { hovered = true }
            onExited: { hovered = false }
        }
        GridLayout {
            anchors.fill: parent
            columns: 2
            Label
            {
                Layout.row: 0
                Layout.column: 0
                text: "Label:"
                Layout.minimumWidth: 80
                Layout.fillHeight: true
                Layout.fillWidth: true
                font.weight: control.activeFocus ? Font.Bold : Font.Normal
            }
            Item // ComboBox // TextInput // Button
            {
                id: ctl
                Layout.row: 0
                Layout.column: 1
                Layout.minimumWidth: 80
                Layout.minimumHeight: 20
                Layout.fillHeight: true
                Layout.fillWidth: true
            }
        }
    }
    

    You can Try it Online!