如何在Qt Quick folderListmodel中实现搜索功能?

时间:2015-04-16 12:10:53

标签: qt qml qtquick2

我希望在我的音乐播放器中实现搜索功能,完全用Qml编写 。在我的情况下,我启动了一个qml Filedialog从文件系统获取文件夹,然后我使用folderListModel通过ListView列出它们。 我想通过列表搜索任何线索我怎样才能实现这个????

请不要建议使用c ++。并且也不建议我在foldelistmodel中使用nameFilters :["*."]因为它不会工作它只根据文件扩展名而不是文件名进行过滤

2 个答案:

答案 0 :(得分:1)

实际上nameFilters允许按文件名过滤。使用一种黑客攻击,甚至可以使它不区分大小写。

这是一个丑陋但有效的例子:

import QtQuick 2.3
import QtQuick.Controls 1.2
import Qt.labs.folderlistmodel 2.1

Item {
    width: 300
    height: 300

    FolderListModel
    {
        id: folderListModel
    }

    function updateFilter()
    {
        var text = filterField.text
        var filter = "*"
        for(var i = 0; i<text.length; i++)
            if(!caseSensitiveCheckbox.checked)
                filter+= "[%1%2]".arg(text[i].toUpperCase()).arg(text[i].toLowerCase())
            else
                filter+= text[i]
        filter+="*"
        print(filter)
        folderListModel.nameFilters = [filter]
    }

    Row
    {
        spacing: 5
        Text {text:"Filter"}
        TextField
        {
            id: filterField
            onTextChanged: updateFilter()
        }

        Text {text:"Case Sensitive"}
        CheckBox
        {
            id: caseSensitiveCheckbox
            checked: false
            onCheckedChanged:updateFilter()
        }
    }

    ListView
    {
        anchors.fill: parent
        anchors.topMargin: 30
        model:folderListModel
        delegate: Text{text: model.fileName}
    }

}

答案 1 :(得分:0)

使用DelegateModel

  

使用DelegateModelGroup对代理项进行排序和过滤。

假设您有一个使用文件名

过滤文件的功能
function willBeShownOnView(filename){ /* ... */ }

您可以通过传递更多角色(fileSizefileIsDir,...)或用户输入的过滤字符串来扩展此功能,并在此功能中实现过滤逻辑。

接下来,使用DelegateModel创建filterGroup

DelegateModel {
    id: delegateModel
    model: FolderListModel{id: folderModel}
    groups: [
        DelegateModelGroup {
            name: "filterGroup"; includeByDefault: true
        }
    ]
    filterOnGroup: "filterGroup"
    delegate: MyFileDisplayComponent{/* ... */}

    function applyFilter(){ /* see below */}
}

作为includeByDefault: truefolderModel中的所有项都包含在filterGroup中。当我们applyFilter时,应该从该组中删除一些项目。例如,

function applyFilter(){
    var numberOfFiles = folderModel.count;
    for (var i = 0; i < numberOfFiles; i++){
        var fileName = folderModel.get(i, "fileName");

        if (willBeShownOnView(fileName)){items.addGroups(i, 1, "filterGroup");}
        else {items.removeGroups(i, 1, "filterGroup");}
    }
}

调用applyFilter后,只有通过willBeShownOnView的文件才会添加到filterGroup。属性filterOnGroup: "filterGroup"表示委托模型仅包含filterGroup中的项目。因此,我们可以使用简单的ListView来显示结果:

ListView { 
    model: delegateModel
    //...
}