Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Filtered model does not work inside a delegate



  • Hi guys,

    I have a problem with an filtered model inside a delegate. I want to display the entries from a database, sorted by date. The data behind the database could be any kind of QAbstractItemModel.

    As an example I have written a simple todo list based on database entries. Here I want to display the corresponding todos next to the respective date.

    From the log output of the Repeater I can see, that some entries are available. But they are not displayed in the grid..

        ColumnLayout {
            anchors.fill: parent
            DayOfWeekRow {
                locale: grid.locale
                Layout.fillWidth: true
            }
    
            MonthGrid {
                id: grid
                month: nowDate.getMonth()
                year: 2019
                locale: Qt.locale("de_DE")
                Layout.fillWidth: true
                Layout.fillHeight: true
    
                contentItem: Grid {
                    rows: 5
                    columns: 7
                    rowSpacing: grid.spacing
                    columnSpacing: grid.spacing
    
                    Repeater {
                        model: grid.source
                        delegate: grid.delegate
                    }
                }
    
                delegate: RowLayout{
                    id: delegate
                    property var delegDate: model.date.toLocaleString(Qt.locale("de_DE"),"yyyy-MM-dd");
    
                    Component.onCompleted: {
                        todoModel.setDateFilter(delegDate)
                    }
    
                    Rectangle {
                        visible: model.month === grid.month
                        Layout.preferredHeight: 40
                        Layout.preferredWidth: 40
                        radius: height/2
                        color: "#ccc"
    
                        Text {
                            anchors.centerIn: parent
                            text: model.day + "." + (model.month+1)
                            font.bold: model.today
                        }
                    }
                    ColumnLayout {
                        visible: model.month === grid.month
                        Repeater{
                            model: todoModel
    
                            Component.onCompleted: {
                                if(model.rowCount() > 0)
                                    console.log("Entries available on " + delegate.delegDate)
                            }
    
                            Text {
                                text: todo
                            }
                        }
                    }
                }
            }
        }
    

    For every day in the CalendarModel (delegate) I put a dateFilter on my todoModel. But the Repeater does not show the filtered entries..

    void TodoModel::setDateFilter(QString date)
    {
        if (m_dateFilter == date)
            return;
    
        m_dateFilter = date;
        updateModel();
    }
    
    void TodoModel::updateModel()
    {
        // The update is performed SQL-queries to the database
        if(m_dateFilter.isEmpty()) {
            this->setQuery("SELECT * FROM " TABLE_DAILYTODOS);
        } else {
            this->setQuery("SELECT * FROM " TABLE_DAILYTODOS " WHERE " COLUMN_DATE "='" +m_dateFilter+ "'");
        }
    }
    

    I hope you can help me to achieve my project.

    [0_1560326438682_RepeaterListview.zip](Uploading 100%)

    PS: How can I share the example project with you? I dont't have the privileges to upload it here..



  • Does no one has similar problems?



  • Hi @Wowalive
    Can you re-upload the image ?

    Hoping the below information could help you.

    In your TodoModel ( Expecting it is inherited from QSortFilterProxyModel )

    Example:

    • TodoModel.h
        Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged)
    
    public:
        enum Filter {
            ShowFirstRow = Qt::UserRole + 1,
            HideFirstRow,
        };
    
        Q_ENUM(Filter)
    
        Filter filter();
        void setFilter(Filter filter);
    
        bool filterAcceptsColumn(int source_row, const QModelIndex &source_parent) const override;
     // or      // As per requirment
        bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
    
    //  if you have different source model
        void setSourceModel(QAbstractItemModel *sourceModel) override; 
    
    • TodoModel.cpp
    TodoModel::Filter TodoModel::filter()
    {
        return m_filter;
    }
    
    void TodoModel::setFilter(TodoModel::Filter filter)
    {
        if (filter == m_filter)
            return;
        m_filter = filter;
        emit filterChanged();
    
        this->invalidateFilter();
    }
    
    • At QML something like below
        ListView {
            id: testView
    
            model: TodoModel {
                sourceModel: // Provide the Source model
                filter: // provide the Filter
            }
    
            delegate: MyDeligate { }
        }
    

    All the best.


Log in to reply