简体   繁体   中英

QML prevent ListView delegate to update all the time

I'm relatively new to QML/QtQuick and still learning. I have a little performane issue with a very small private project. I just tryed to implement a filter function to my ListView, because >15.000 objects are a lot to search manually. I just want to update the ListView when I finished the editing of my search field or pressing "return". But instead it's refreshing every time I insert or delete a character from this textfield which needs sometimes a few seconds.

Anyone have an idea how to prevent the list to be refreshed permanently or reducing theese performance issues?

Thanks a lot

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.XmlListModel 2.12
import Anime_initialiser  1.0
import "."

Page {
    TextField{
        id: searchField
        width: parent.width
        z: 1
        /*onEditingFinished: {
            XL.animeListModel.reload()
        }*/
    }
    ListView {
        z: 0
        ScrollBar.vertical: ScrollBar { active: true }
        id: listView
        width: parent.width
        height: parent.height
        model: XL.animeListModel
        y: searchField.height
        Anime_initialiser {
            id: initialiser
            onShowAnimeDetails: {
                xmlDataString = xmlString
                swipeView.currentIndex = swipeView.currentIndex+1
            }
        }
        delegate: ItemDelegate {
            visible: {
                if (searchField.length > 0)
                    return (main_title.toLowerCase().match(searchField.text.toLowerCase()) || de_title.toLowerCase().match(searchField.text.toLowerCase())) ? true : false
                else
                    return true
            }
            height:  visible ? Button.height : 0
            width: parent ? parent.width : 0
            Button {
                anchors.fill: parent
                onClicked: {
                    anime_id = aid
                    initialiser.buttonClicked(anime_id)
                }
                Text {
                    width: parent.width
                    height: parent.height
                    font.pointSize: 100
                    minimumPointSize: 12
                    fontSizeMode: Text.Fit
                    text: aid + ": " + main_title + (de_title ? "\nDE: " + de_title : "")
                }
            }
        }
    }
}

Rather than toggling the visible flag of all of your delegates, you should use a QSortFilterProxyModel . The idea is that the proxy model would use your XL.animeListModel as a source model, and then you can give the proxy a regular expression telling it which ones to filter out. Depending on how you want it to filter, you could just call setFilterRole() to tell it which property to compare against your regex, or you could do a custom filter by overriding the filterAcceptsRow() function.

EDIT :

If you don't want to use a proxy, you can still prevent the constant updates by not binding on the visible property directly to the search field. You were on the right track with your onEditingFinished code. You could create a separate text string that just holds the completed search text.

property string searchText: ""

Then update that string when you are done typing your search text.

onEditingFinished: {
    searchText = searchField.text.toLowerCase();
}

And finally, bind your visible property to this new string.

            visible: {
                if (searchText.length > 0)
                    return (main_title.toLowerCase().match(searchText) || de_title.toLowerCase().match(searchText)) ? true : false
                else
                    return true
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM