qt - How to use the CheckBox to the filter Listview in qml? - Stack Overflow

admin2025-04-15  0

In .qml I'm generating the Listview based on the .json file below. I'm able to filter the list bases on the "PinName" alone via TextField of the Frame QML type. I also need to be able to use CheckBox type to filter the "Make"

{
    "Toyota" :
    [
        { 
            "Make": "RAV4",    
            "PinName": "J1-A3/A4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Reverse Output" 
        },
        { 
            "Make": "RAV4",    
            "PinName":"J1-C1",
            "PinType": "Analogue",
            "PinDirection": "Input",  
            "Function Name": "Fuel Sensor Signal" 
        },
        { 
            "Make": "Fortuner",
            "PinName": "J1-C2",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "Generic Spare" 
        },
        { 
            "Make": "Fortuner",
            "PinName": "J1-C3/C4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Bin Marker Lights" 
        },
        {
            "Make": "Corolla", 
            "PinName": "J1-D1",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "DiffLock Switch (CTD)" 
        },
        { 
            "Make": "Corolla", 
            "PinName": "J1-D2",    
            "PinType": "Tristate", 
            "PinDirection": "Output", 
            "Function Name": "Park Brake Press Switch" 
        }
    
    ],

    "Volkswagen":
    [
        { 
            "Make": "Polo",   
            "PinName": "J1-A3/A4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Reverse Output" 
        },
        { 
            "Make": "Polo",   
            "PinName": "J1-C1",    
            "PinType": "Analogue", 
            "PinDirection": "Input",  
            "Function Name": "Fuel Sensor Signal" 
        },
        { 
            "Make": "Taigo",  
            "PinName": "J1-C2",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "Generic Spare" 
        },
        { 
            "Make": "Taigo",  
            "PinName": "J1-C3/C4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Bin Marker Lights" 
        },
        { 
            "Make": "Tiguan", 
            "PinName": "J1-D1",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "DiffLock Switch (CTD)" 
        },
        { 
            "Make": "Tiguan", 
            "PinName": "J1-D2",    
            "PinType": "Tristate", 
            "PinDirection": "Output", 
            "Function Name": "Park Brake Press Switch" 
        }
    ] 
}

I have implemented the Listview model as follows:

ListView {
        id: pinListView
        Layout.fillWidth: true
        Layout.fillHeight: true
        clip: true
        model: FilterDelegateModel {
            id: filterDelegateModel
            model: pinModel
            filter: search ? function(model){
                var isFound = false ;
                var i = 0 ;
                //===================================================

                const pattern = search.trim() ;
                if(pattern.length > 0){
                    var regex = new RegExp(pattern,'i' /*ignore case*/);  //What does this do????

                    isFound = (regex.test(model.Make+ model.FunctionName )) ;
                }

                return isFound ;
            } : null
            property string search: searchTextEdit.text.trim().toLowerCase()
            onSearchChanged: Qt.callLater(update)
            delegate: Frame {
                id: frame
                property int visibleIndex: DelegateModel.visibleIndex
                width: ListView.view.width
                background: Rectangle {
                    color: visibleIndex & 1 ? "#404040" : "#343434"
                    border.color: "#7D7D7D"
                    border.width: 1
                }
                RowLayout {
                    id: layout
                    anchors.fill: parent
                    spacing: 6
                    Text {
                        text: (visibleIndex + 1)
                        color: "#fdbb30"
                        font.bold: true
                        font.pointSize: 9
                    }
                    Text {
                        Layout.fillWidth: true
                        text: model.functionName+" - "+"["+model.make+"]"
                        color: "white" //"#fdbb30"
                        font.bold: true
                        font.pointSize: 9
                    }

                    Rectangle {
                        color: 'transparent'//'transparent'//'plum'
                        Layout.alignment: Qt.AlignLeft
                        //Layout.fillWidth: true
                        Layout.minimumWidth: 50
                        Layout.preferredWidth: layout.width*0.5
                        Layout.maximumWidth: layout.width*0.5
                        Layout.minimumHeight: 40

                        Loader {
                            id: controlLoader
                         //   sourceComponent: pinListView.getPinControl(model.direction, model.type)
                            anchors.centerIn: parent
                        }
                    }
                } //RowLayout
            }//Frame
        }//FilterDelegateModel
    } //ListView

In .qml I'm generating the Listview based on the .json file below. I'm able to filter the list bases on the "PinName" alone via TextField of the Frame QML type. I also need to be able to use CheckBox type to filter the "Make"

{
    "Toyota" :
    [
        { 
            "Make": "RAV4",    
            "PinName": "J1-A3/A4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Reverse Output" 
        },
        { 
            "Make": "RAV4",    
            "PinName":"J1-C1",
            "PinType": "Analogue",
            "PinDirection": "Input",  
            "Function Name": "Fuel Sensor Signal" 
        },
        { 
            "Make": "Fortuner",
            "PinName": "J1-C2",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "Generic Spare" 
        },
        { 
            "Make": "Fortuner",
            "PinName": "J1-C3/C4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Bin Marker Lights" 
        },
        {
            "Make": "Corolla", 
            "PinName": "J1-D1",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "DiffLock Switch (CTD)" 
        },
        { 
            "Make": "Corolla", 
            "PinName": "J1-D2",    
            "PinType": "Tristate", 
            "PinDirection": "Output", 
            "Function Name": "Park Brake Press Switch" 
        }
    
    ],

    "Volkswagen":
    [
        { 
            "Make": "Polo",   
            "PinName": "J1-A3/A4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Reverse Output" 
        },
        { 
            "Make": "Polo",   
            "PinName": "J1-C1",    
            "PinType": "Analogue", 
            "PinDirection": "Input",  
            "Function Name": "Fuel Sensor Signal" 
        },
        { 
            "Make": "Taigo",  
            "PinName": "J1-C2",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "Generic Spare" 
        },
        { 
            "Make": "Taigo",  
            "PinName": "J1-C3/C4", 
            "PinType": "Digital",  
            "PinDirection": "Output", 
            "Function Name": "Bin Marker Lights" 
        },
        { 
            "Make": "Tiguan", 
            "PinName": "J1-D1",    
            "PinType": "Tristate", 
            "PinDirection": "Input",  
            "Function Name": "DiffLock Switch (CTD)" 
        },
        { 
            "Make": "Tiguan", 
            "PinName": "J1-D2",    
            "PinType": "Tristate", 
            "PinDirection": "Output", 
            "Function Name": "Park Brake Press Switch" 
        }
    ] 
}

I have implemented the Listview model as follows:

ListView {
        id: pinListView
        Layout.fillWidth: true
        Layout.fillHeight: true
        clip: true
        model: FilterDelegateModel {
            id: filterDelegateModel
            model: pinModel
            filter: search ? function(model){
                var isFound = false ;
                var i = 0 ;
                //===================================================

                const pattern = search.trim() ;
                if(pattern.length > 0){
                    var regex = new RegExp(pattern,'i' /*ignore case*/);  //What does this do????

                    isFound = (regex.test(model.Make+ model.FunctionName )) ;
                }

                return isFound ;
            } : null
            property string search: searchTextEdit.text.trim().toLowerCase()
            onSearchChanged: Qt.callLater(update)
            delegate: Frame {
                id: frame
                property int visibleIndex: DelegateModel.visibleIndex
                width: ListView.view.width
                background: Rectangle {
                    color: visibleIndex & 1 ? "#404040" : "#343434"
                    border.color: "#7D7D7D"
                    border.width: 1
                }
                RowLayout {
                    id: layout
                    anchors.fill: parent
                    spacing: 6
                    Text {
                        text: (visibleIndex + 1)
                        color: "#fdbb30"
                        font.bold: true
                        font.pointSize: 9
                    }
                    Text {
                        Layout.fillWidth: true
                        text: model.functionName+" - "+"["+model.make+"]"
                        color: "white" //"#fdbb30"
                        font.bold: true
                        font.pointSize: 9
                    }

                    Rectangle {
                        color: 'transparent'//'transparent'//'plum'
                        Layout.alignment: Qt.AlignLeft
                        //Layout.fillWidth: true
                        Layout.minimumWidth: 50
                        Layout.preferredWidth: layout.width*0.5
                        Layout.maximumWidth: layout.width*0.5
                        Layout.minimumHeight: 40

                        Loader {
                            id: controlLoader
                         //   sourceComponent: pinListView.getPinControl(model.direction, model.type)
                            anchors.centerIn: parent
                        }
                    }
                } //RowLayout
            }//Frame
        }//FilterDelegateModel
    } //ListView
Share Improve this question edited Feb 4 at 12:54 eyllanesc 245k19 gold badges201 silver badges280 bronze badges asked Feb 4 at 12:38 Clive NClive N 371 silver badge6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

As of Qt6.4+ with the QML list type, in particularly, list<var> behaves similarly to Javascript arrays and supports the filter which is good for search.

To get this to work:

  1. I put your JSON object in a property, i.e. property var raw_data
  2. I walk the JSON object producing a flatten list, i.e. property list<var> pin_data
  3. Then, the formula comes down to declaring appropriate logic for pin_data.filter() to switch between PinName/Functon to Make search based on the Search textfield and Make checkbox
Page {
    property var raw_data: ({
        "Toyota" :
        [
            /* ... */
        ],
        "Volkswagen" :
        [
            /* ... */
        ],
    })
    
    property list<var> pin_data: {
        var result = [ ];
        for (let brand in raw_data) {
            for (let pin of raw_data[brand]) {
                pin.Brand = brand;
                result.push(pin);
            }
        }
        return result;
    }
    
    header: RowLayout {
        TextField {
            id: search
            Layout.fillWidth: true
            placeholderText: make.checked ? "Make Search" : "PinData/Function Search"
        }
        CheckBox { id: make; text: "Make" }
    }
    
    ListView {
        anchors.fill: parent
        model: pin_data.filter(
                   m => !search.text
                   || (make.checked ? m.Make : m.PinName + " " + m["Function Name"])
                      .toLowerCase()
                      .indexOf(search.text.toLowerCase()) != -1)
        delegate: Frame {
            width: ListView.view.width
            ColumnLayout {
                Label { text: `Brand: ${modelData["Brand"]}` }
                Label { text: `Make: ${modelData["Make"]}` }
                Label { text: `Function Name: ${modelData["Function Name"]}` }
                Label { text: `PinDirection: ${modelData["PinDirection"]}` }
                Label { text: `PinName: ${modelData["PinName"]}` }
                Label { text: `PinType: ${modelData["PinType"]}` }
            }
        }
    }
}

You can Try it Online!

For Qt 5 compatibility, we can declare the array inline with the ListView.model as follows:

        model: {
            var result = [ ];
            for (var brand in raw_data) {
                for (var pin of raw_data[brand]) {
                    pin.Brand = brand;
                    result.push(pin);
                }
            }
            return result.filter(
                        m => !search.text
                        || (make.checked ? m.Make : m.PinName + " " + m["Function Name"])
                           .toLowerCase()
                           .indexOf(search.text.toLowerCase()) != -1);
        }

You can Try this Qt5 compatible version online

转载请注明原文地址:http://www.anycun.com/QandA/1744719089a86668.html