3
votes

It's possible to hide certain cell in GridView? I set delegate, but I still got empty place for this GridView element. It's possible to do this?

visible: false
width: 0
height: 0
2
What do you mean by hiding, for example if the delegate is a rectangle and it is in the middle you want that space to be empty, or do not leave any space.eyllanesc
Second case, I want hide one cell in a grid and reorder other cells to not leave free space.kluszon
What is your model?eyllanesc
It looks lke you're talking about Layout.rowSpanfolibis
@eyllanesc QSortFilterProxyModel is one of solution. Other one is change GridView on Grid with Repeater inside and all in Flickable. It look the same, work the same and I can hide certain item using visible, height and width.kluszon

2 Answers

2
votes

As was said in the comment, you can indeed use a QSortFilterProxy model, but here is another solution. You could implement a pure-QML FilterProxyModel, using DelegateModel and DelegateModelGroup

import QtQuick 2.10
import QtQml.Models 2.3

DelegateModel {

    property var filterAccepts: function(item) {
        return true
    }

    onFilterAcceptsChanged: refilter()

    function refilter() {
        if(hidden.count>0)
            hidden.setGroups(0, hidden.count, "default")
        if(items.count>0)
            items.setGroups(0, items.count, "default")
    }

    function filter() {
        while (unsortedItems.count > 0) {
            var item = unsortedItems.get(0)
            if(filterAccepts(item.model))
                item.groups = "items"
            else
                item.groups = "hidden"
        }
    }

    items.includeByDefault: false
    groups: [
        DelegateModelGroup {
            id: default
            name: "default"
            includeByDefault: true
            onChanged: filter()
        },
        DelegateModelGroup {
            id: hidden
            name: "hidden"
        }
    ]

}

Explanation: Every time an item is added to the model, it is added in the "default" group, which triggers the onChanged handler that will call filter().

Filter() will look for items in the default group, and move them either in the items group (which will make them visible) or to the hidden group, depending on the result of the filterAccepts function.

When filterAccept changes, the SortProxyModel will move every item to the default group to trigger a global refiltering.

You can then use your proxy model like this:

FilterProxyModel
{
    id: filterProxyModel

    model: <YourBaseModel>
    delegate: <YourDelegate>

    filterAccepts: function(item) {
          // Eg: Only "small" items will be displayed
          return item.size == "small"
    }
}

GridView
{
    anchors.fill: parent
    model: filterProxyModel
    cellHeight: 100
    cellWidth: 100
}
0
votes

Another simplified solution with QML only, based on hiding items.

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Layouts 1.2

Window {
    id: window
    title: "test"
    visible: true
    width: 400
    height: 400
    GridLayout {
        id: layout
        anchors.fill: parent
        columns: 4
        Repeater {
            id: container
            model: 20
            Rectangle {
                id: item
                property int itemIndex: index
                Layout.fillWidth: true
                height: 60
                color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
                Text {
                    anchors.centerIn: parent
                    text:item.itemIndex
                }

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        item.visible = false;
                        layout.doIt(item.itemIndex);
                    }
                }
            }
        }
        function doIt(index)
        {
            var item = container.itemAt(index);
            if(item)
                item.visible = false;
            for(var i = index - 1;i >= 0;i --)
            {
                var prev_item = container.itemAt(i);
                if(prev_item.visible) {
                    prev_item.Layout.columnSpan ++;
                    break;
                }
            }
        }
    }
}