Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt QML如何通过单击列的标题对tableView进行排序_Qt_Sorting_Search_Qml_Tableview - Fatal编程技术网

Qt QML如何通过单击列的标题对tableView进行排序

Qt QML如何通过单击列的标题对tableView进行排序,qt,sorting,search,qml,tableview,Qt,Sorting,Search,Qml,Tableview,所以在我的项目中,我使用了一个具有模型的tableview:TableModelFopm Qt.labs.qmlmodels 1.0; 所以我想用一些方法对它进行排序,我发现类QabStructProxyModel,我不知道我是否使用得很好,但我发现过滤和排序方面的问题在我的代码下面,请提前感谢需要帮助的人 import QtQuick 2.15 import QtQuick.Window 2.12 import Qt.labs.qmlmodels 1.0 import QtQuick.

所以在我的项目中,我使用了一个具有模型的tableview:TableModelFopm Qt.labs.qmlmodels 1.0; 所以我想用一些方法对它进行排序,我发现类QabStructProxyModel,我不知道我是否使用得很好,但我发现过滤和排序方面的问题在我的代码下面,请提前感谢需要帮助的人

    import QtQuick 2.15
import QtQuick.Window 2.12
import Qt.labs.qmlmodels 1.0
import QtQuick.Controls 2.15
import QtQml.Models 2.15

import org.qtproject.example 1.0

ApplicationWindow {
    width: 1000
    height: 400
    visible: true

     header: ToolBar {
        TextField {
            id: searchBox


            placeholderText: "Search..."
            inputMethodHints: Qt.ImhNoPredictiveText

            //width: window.width / 5 * 2
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
        }
    }



    TableView {
        id:tableView
        anchors.fill: parent
        //sortIndicatorVisible: true

        //anchors.topMargin: 30
        columnSpacing: 1
        rowSpacing: 3
        anchors.topMargin:30
        //boundsBehavior: Flickable.StopAtBounds



        model:SortFilterProxyModel {
            id: proxyModel
            source: sourceModel.rowCount> 0 ? sourceModel : null
            onSourceChanged: console.log(source+" source")

            sortOrder: Qt.AscendingOrder//tableView.sortIndicatorOrder

            sortCaseSensitivity: Qt.CaseInsensitive
            sortRole: sourceModel.rowCount > 0 ? " nomdetrame": ""
            onSortRoleChanged: console.log(" role")
            filterString: "*" + searchBox.text + "*"
            //onFilterStringChanged: console.log(filterString)
            filterSyntax: SortFilterProxyModel.Wildcard
            filterCaseSensitivity: Qt.CaseInsensitive
        }

            TableModel {
            id:sourceModel


            TableModelColumn{ display: " teta"}
            TableModelColumn { display: "visibilite" }
            TableModelColumn { display: "couleur" }
            TableModelColumn{ display: "chaine_can"}
            TableModelColumn{ display: "nomdetrame" }
            TableModelColumn{ display: "nondusignal"}
            TableModelColumn { display: "valeurDec" }
            TableModelColumn { display: "valeurHex" }
            TableModelColumn { display: "TxouRx" }


            // Each row is one type of fruit that can be ordered
            rows: [
                {
                    // Each property is one cell/column.
                    teta:"+",
                    visibilite: false,
                    couleur: "red",
                    chaine_can: "CAN 4",
                    nomdetrame: "rRX",
                    nondusignal: "1.50",
                    valeurDec: "CAN 4",
                    valeurHex: "rRX",
                    TxouRx: "Tx"
                },
                {   teta:"+",
                    visibilite: false,
                    couleur: "grey",
                    chaine_can: "CAN 1",
                    nomdetrame: "rRX",
                    nondusignal: "1.5",
                    valeurDec: "CAN 4",
                    valeurHex: "rRX",
                    TxouRx: "Rx"
                },
                {   teta:"+",
                    visibilite: true,
                    couleur: "black",
                    chaine_can: "CAN 2",
                    nomdetrame: "rRX",
                    nondusignal: "1",
                    valeurDec: "CAN 4",
                    valeurHex: "RXE",
                    TxouRx: "Tx"
                }
            ]



        }





        delegate:  DelegateChooser {

            DelegateChoice{
                column: 0
                //width: 100
            delegate:Button{
                    id:teta
                    text:"+"
                    //anchors.fill: parent
                    onClicked:{tableView.sourceModel.appendRow({
                                                   // Each property is one cell/column.
                                                   teta:"+",
                                                   visibilite: false,
                                                   couleur: "red",
                                                   chaine_can: "CAN 4",
                                                   nomdetrame: "rRX",
                                                   nondusignal: "1.50",
                                                   valeurDec: "CAN 4",
                                                   valeurHex: "rRX",
                                                   TxouRx: "Tx"
                                               }
                                               )}

                }
                //z: -1
            }

            DelegateChoice{
                column: 1
            delegate:Rectangle{
                border.color: "black"
                implicitWidth: 80
                CheckBox{
                //anchors.fill: parent
                    anchors.centerIn: parent
                checked: model.display


            }
        }
            }
            DelegateChoice{
                column: 2
            delegate:Rectangle {
                implicitWidth: 80
                //anchors.fill: parent
                 border.color: "black"
                color: model.display
                //z: -1
            }
        }
            DelegateChoice{
                column: 3
            delegate:Rectangle{
                border.color:"black"
                implicitWidth: 80

                Button{
                    anchors.fill: parent
                    onClicked: console.log(currentIndex)
//                    TextInput {
//                        //textRole: "display"
//                    anchors.fill: parent
//                    text:model.display
//                    //z: -1
//                }
                }


        }
            }
            DelegateChoice{
                column: 4
           delegate:Rectangle{
               border.color: "black"
               implicitWidth: 80
               TextInput {
                //anchors.fill: parent
                   anchors.centerIn: parent
                text:model.display
                //z: -1
            }
        }
            }
            DelegateChoice{
                column: 5
            delegate:Rectangle{
                border.color: "black"
                implicitWidth: 80
                TextInput {
                //anchors.fill: parent
                    anchors.centerIn: parent
                text:model.display
                //z: -1
            }
        }
            }
            DelegateChoice{
                column: 6
            delegate:Rectangle{
                implicitWidth: 80
                border.color: "black"
                TextInput {
//                anchors.fill: parent
                    anchors.centerIn: parent
                text:model.display
                //z: -1
            }
        }
            }
            DelegateChoice{
                column: 7
            delegate:Rectangle{
                implicitWidth: 80
                border.color: "black"

                TextInput {
                //anchors.fill: parent
                    anchors.centerIn: parent
                text:model.display
                //z: -1
            }
        }
            }
            DelegateChoice{
                column: 8
            delegate:Rectangle{
                implicitWidth: 80
                border.color: "black"
                TextInput {
                //anchors.fill: parent
                    anchors.centerIn: parent
                text:model.display

                //z: -1
            }
            }
        }


    }
        Component.onCompleted: {
            console.log(searchBox.text)
            //console.log(tableView.model.getRow(0).couleur)}

}
    }
    HorizontalHeaderView{
        id:headerView
        anchors.left: tableView.left
      syncView: tableView
      model:[" ","Visible","Couleur","Chaine_Can","NomTrame","NomSignal","ValeurDec","ValeurHex","TX/RX"]





        MouseArea{
            id:ms
            anchors.fill: parent
            hoverEnabled: true


        }

    }




}

c++代码:

include "sortfilterproxymodel.h"
#include <QtDebug>
#include <QtQml>

SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent), m_complete(false)
{
    connect(this, &QSortFilterProxyModel::rowsInserted, this, &SortFilterProxyModel::countChanged);
    connect(this, &QSortFilterProxyModel::rowsRemoved, this, &SortFilterProxyModel::countChanged);
    qDebug()<<"je suis entré chez moi";
}

int SortFilterProxyModel::count() const
{
    return rowCount();
}

QObject *SortFilterProxyModel::source() const
{
    return sourceModel();
}

void SortFilterProxyModel::setSource(QObject *source)
{
    setSourceModel(qobject_cast<QAbstractItemModel *>(source));
    emit sourceChanged();
}

QByteArray SortFilterProxyModel::sortRole() const
{
    return m_sortRole;
}

void SortFilterProxyModel::setSortRole(const QByteArray &role)
{
    if (m_sortRole != role) {
        m_sortRole = role;
        if (m_complete)
            QSortFilterProxyModel::setSortRole(roleKey(role));
    }
}

void SortFilterProxyModel::setSortOrder(Qt::SortOrder order)
{
    QSortFilterProxyModel::sort(0, order);
}

QByteArray SortFilterProxyModel::filterRole() const
{
    return m_filterRole;
}

void SortFilterProxyModel::setFilterRole(const QByteArray &role)
{
    if (m_filterRole != role) {
        m_filterRole = role;
        if (m_complete)
            QSortFilterProxyModel::setFilterRole(roleKey(role));
    }
}

QString SortFilterProxyModel::filterString() const
{
    return filterRegExp().pattern();
}

void SortFilterProxyModel::setFilterString(const QString &filter)
{

    setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(filterSyntax())));
    emit filterStringChanged();
}


SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const
{
    return static_cast<FilterSyntax>(filterRegExp().patternSyntax());
}

void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax)
{
    setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax)));
}

QJSValue SortFilterProxyModel::get(int idx) const
{
    QJSEngine *engine = qmlEngine(this);
    QJSValue value = engine->newObject();
    if (idx >= 0 && idx < count()) {
        QHash<int, QByteArray> roles = roleNames();
        for (auto it = roles.cbegin(), end = roles.cend(); it != end; ++it)
            value.setProperty(QString::fromUtf8(it.value()), data(index(idx, 0), it.key()).toString());
    }
    return value;
}

void SortFilterProxyModel::classBegin()
{
}

void SortFilterProxyModel::componentComplete()
{
    m_complete = true;

    if (!m_sortRole.isEmpty())
        QSortFilterProxyModel::setSortRole(roleKey(m_sortRole));

    if (!m_filterRole.isEmpty())
        QSortFilterProxyModel::setFilterRole(roleKey(m_filterRole));

}

int SortFilterProxyModel::roleKey(const QByteArray &role) const
{
    return roleNames().key(role, -1);

}

QHash<int, QByteArray> SortFilterProxyModel::roleNames() const
{
    qDebug()<<"RoleNames";
    if (QAbstractItemModel *source = sourceModel()){
        qDebug()<<"RoleNames";
        //qDebug()<< source->roleNames();
                    //qDebug()<<roleNames().key(0)<< " keys";
        return source->roleNames();}
    return QHash<int, QByteArray>();
}

bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QRegExp rx = filterRegExp();
    if (rx.isEmpty())
        return true;
    QAbstractItemModel *model = sourceModel();
    if (filterRole().isEmpty()) {
        QHash<int, QByteArray> roles = roleNames();
        for (auto it = roles.cbegin(), end = roles.cend(); it != end; ++it) {
            QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
            QString key = model->data(sourceIndex, it.key()).toString();
            if (key.contains(rx))
                return true;
        }
        return false;
    }
    QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
    if (!sourceIndex.isValid())
        return true;
    QString key = model->data(sourceIndex, roleKey(filterRole())).toString();
    qDebug()<<rx;
    return key.contains(rx);
}

包括“sortfilterproxymodel.h”
#包括
#包括
SortFilterProxyModel::SortFilterProxyModel(QObject*父对象):QSortFilterProxyModel(父对象),m_complete(false)
{
连接(this,&QSortFilterProxyModel::rowsInserted,this,&SortFilterProxyModel::countChanged);
连接(此,&QSortFilterProxyModel::rowsRemoved,此,&SortFilterProxyModel::countChanged);
qDebug()=0&&idxqDebug()我无法运行您的代码。因为我使用的是较旧版本的Qt。因此,我使用重新实现的QSortFilterProxyModel类制作了一个简单的工作原型,并在qml中使用它进行筛选和排序。我的源模型是一个列表视图,在您的示例中,它是一个表视图。其他方面也是一样的

代码的可能部分需要检查。 1.重新实施
filterAcceptsRow
2.重新实施
lessThan
3.确保在更改搜索文本时调用
invalidateFilter
4.确保在更改排序器时调用默认的
sort
函数

================此处的示例代码============

************** main.qml **************
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

import SortFilter 1.0

Window {
    id: rootId
    width: 320
    height: 568
    visible: true

    SortFilterProxy {
        id: sortFilterProxyModelId
        sourceModel: fruitModel
        sortRole: Qt.DisplayRole
        searchString: ""
        sortOrder: Qt.AscendingOrder
    }

    ListModel {
        id: fruitModel
        ListElement { name: "Apple" }
        ListElement { name: "Orange" }
        ListElement { name: "Banana" }
    }

    Column {
        anchors.fill: parent

        TextField {
            id: searchIpId
            height: 40
            width: parent.width
            focus: true
            placeholderText: "Enter search text"
            onTextChanged: sortFilterProxyModelId.searchString = text

            Button {
                id: sortButtonId
                height: parent.height - 10
                width: 60
                text: "sort"
                anchors.rightMargin: 10
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    // call proxy
                    if(sortFilterProxyModelId.sortOrder == Qt.AscendingOrder)
                        sortFilterProxyModelId.sortOrder = Qt.DescendingOrder
                    else
                        sortFilterProxyModelId.sortOrder = Qt.AscendingOrder
                    searchIpId.forceActiveFocus()
                }
            }
        }

        ListView {
            width: parent.width
            height: parent.height - searchIpId.height
            model: sortFilterProxyModelId // change to proxy output
            delegate: Rectangle {
                width: parent.width
                height: 40
                color: index % 2 == 0 ? "white" : "#C0C0C0"
                Label {
                    anchors.fill: parent
                    anchors.margins: 10
                    text: name
                }
            }
        }
    }
}


************** sortfilterproxymodel.h **************
#ifndef SORTPROXYMODEL_H
#define SORTPROXYMODEL_H

#include <QSortFilterProxyModel>

class SortFilterProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT
    Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
    Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
public:
    explicit SortFilterProxyModel(QObject* parent = nullptr);

    QString searchString() const
    {
        return _searchString;
    }
    Qt::SortOrder sortOrder() const
    {
        return _sortOrder;
    }
    void setSearchString(const QString &searchString);
    void setSortOrder(const Qt::SortOrder &sortOrder);

signals:
    void searchStringChanged(QString searchString);
    void sortOrderChanged(Qt::SortOrder sortOrder);

protected:
    bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;   // custom sort logic
    bool filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const;             // custom filter logic

private:
    QString _searchString;
    Qt::SortOrder _sortOrder;
};

#endif // SORTPROXYMODEL_H


************** sortfilterproxymodel.cpp **************
 #include "sortfilterproxymodel.h"

SortFilterProxyModel::SortFilterProxyModel(QObject* parent) :
    QSortFilterProxyModel(parent)
{
    connect(this, &SortFilterProxyModel::searchStringChanged, this, &SortFilterProxyModel::invalidate); //
}

void SortFilterProxyModel::setSearchString(const QString &searchString)
{
    if (_searchString == searchString)
        return;

    _searchString = searchString;
    emit searchStringChanged(searchString); // connected with invalidateFilter, internally invalidateFilter makes call to filterAcceptsRow function
}

void SortFilterProxyModel::setSortOrder(const Qt::SortOrder &sortOrder)
{
    if(_sortOrder == sortOrder)
        return ;
    _sortOrder = sortOrder;
    sort(0, sortOrder);         // responsible call to make sorting, internally it will make a call to lessthan function
    emit sortOrderChanged(sortOrder);
}

bool SortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    QVariant left = sourceModel()->data(source_left);
    QVariant right = sourceModel()->data(source_right);

    if(left.isValid() && right.isValid())
    {
        return left.toString() > right.toString();
    } else
    {
        return false;
    }
}

bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    QString data = sourceModel()->data(index, Qt::DisplayRole).value<QString>();

    if(_searchString.isEmpty() || _searchString.isNull())
        return true;

    if(data.contains(_searchString, Qt::CaseInsensitive))
        return true;

    return false;
}


*************main.qml**************
导入QtQuick 2.9
导入QtQuick.Window 2.2
导入QtQuick.Controls 2.2
导入SortFilter 1.0
窗口{
id:rootId
宽度:320
身高:568
可见:正确
酸滤氧化{
id:sortFilterProxyModelId
sourceModel:水果模型
sortRole:Qt.DisplayRole
搜索字符串:“
排序器:Qt.AscendingOrder
}
列表模型{
id:水果模型
ListElement{name:“Apple”}
ListElement{name:“Orange”}
ListElement{name:“香蕉”}
}
纵队{
锚定。填充:父级
文本字段{
id:searchIpId
身高:40
宽度:parent.width
焦点:正确
占位符文本:“输入搜索文本”
ContextChanged:sortFilterProxyModelId.searchString=text
钮扣{
id:sortButtonId
高度:parent.height-10
宽度:60
文本:“排序”
1.右页边距:10
anchors.right:父项.right
anchors.verticalCenter:父级.verticalCenter
再次点击:{
//呼叫代理
if(sortFilterProxyModelId.sortOrder==Qt.AscendingOrder)
sortFilterProxyModelId.sortOrder=Qt.DowningOrder
其他的
sortFilterProxyModelId.sortOrder=Qt.AscendingOrder
searchIpId.forceActiveFocus()
}
}
}
列表视图{
宽度:parent.width
高度:parent.height-searchIpId.height
模型:sortFilterProxyModelId//更改为代理输出
代表:矩形{
宽度:parent.width
身高:40
颜色:索引%2==0?“白色”:“#C0”
标签{
锚定。填充:父级
2.5.2.利润率:10
文本:名称
}
}
}
}
}
**************sortfilterproxymodel.h**************
#ifndef SORTPROXY模型
#定义SortProxy模型
#包括
类SortFilterProxyModel:公共QSortFilterProxyModel
{
Q_对象
Q_属性(QString searchString读取searchString写入setSearchString通知searchStringChanged)
Q_属性(Qt::SortOrder SortOrder读取SortOrder写入设置SortOrder通知sortOrderChanged)
公众:
显式SortFilterProxyModel(QObject*parent=nullptr);
QString searchString()常量
{
返回搜索字符串;
}
Qt::SortOrder SortOrder()常量
{
返回-排序器;
}
void setSearchString(const QString和searchString);
无效设置排序顺序(常量Qt::排序器和排序器);
信号:
作废searchStringChanged(QString searchString);
void sortOrderChanged(Qt::SortOrder SortOrder);
受保护的:
bool lessThan(const QModelIndex&source_左,const QModelIndex&source_右)const;//自定义排序逻辑
bool filterAcceptsRow(int sourceRow,const QModelIndex&sourceParent)const;//自定义筛选器逻辑
私人:
QString_searchString;
Qt::SortOrder _SortOrder;
};
#endif//sortproxy模型
**************sortfilterproxymodel.cpp**************
#包括“sortfilterproxymodel.h”
SortFilterProxyModel::SortFilterProxyModel(QObject*父对象):
QSortFilterProxyModel(父级)
{
连接(此,&SortFilterProxyModel::searchStringChanged,此,&SortFilterProxyModel::invalidate)//
}
void SortFilterProxyModel::setSearchString(const QString和searchString)
{
if(_searchString==searchString)
返回;
_searchString=searchString;
发出searchStringChanged(searchString);//与invalidateFilter、inter连接