Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Filtered model does not work inside a delegate
Forum Updated to NodeBB v4.3 + New Features

Filtered model does not work inside a delegate

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 2 Posters 363 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    Wowalive
    wrote on last edited by Wowalive
    #1

    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..

    1 Reply Last reply
    0
    • W Offline
      W Offline
      Wowalive
      wrote on last edited by
      #2

      Does no one has similar problems?

      1 Reply Last reply
      0
      • Pradeep P NP Offline
        Pradeep P NP Offline
        Pradeep P N
        wrote on last edited by Pradeep P N
        #3

        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.

        Pradeep Nimbalkar.
        Upvote the answer(s) that helped you to solve the issue...
        Keep code clean.

        1 Reply Last reply
        1

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved