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..
-
Hi @Wowalive
Can you re-upload the image ?Hoping the below information could help you.
In your TodoModel ( Expecting it is inherited from QSortFilterProxyModel )
- Have you tried filterAcceptsColumn or filterAcceptsRow.
- Also setSourceModel if you have different source model.
- invalidateFilter() function should be called if you are implementing custom filtering.
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.