Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.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 ListView中的角色对QAbstractListModel派生模型排序_Qt_Sorting_Qml_Qabstractlistmodel_Qsortfilterproxymodel - Fatal编程技术网

Qt 按QML ListView中的角色对QAbstractListModel派生模型排序

Qt 按QML ListView中的角色对QAbstractListModel派生模型排序,qt,sorting,qml,qabstractlistmodel,qsortfilterproxymodel,Qt,Sorting,Qml,Qabstractlistmodel,Qsortfilterproxymodel,我已经创建了一个基于基础QHash的QAbstractListModel派生模型。因为我需要在QML中使用模型,所以我无法使用Qt小部件和视图集成的排序功能 我尝试使用QSortFilterProxy模型,但它似乎不适用于我的模型。让模型在QML中正常工作还不够乏味,现在我被困在排序上 如有任何建议,我们将不胜感激 以下是模型来源: typedef QHash<QString, uint> Data; class NewModel : public QAbstractListMod

我已经创建了一个基于基础QHash的QAbstractListModel派生模型。因为我需要在QML中使用模型,所以我无法使用Qt小部件和视图集成的排序功能

我尝试使用QSortFilterProxy模型,但它似乎不适用于我的模型。让模型在QML中正常工作还不够乏味,现在我被困在排序上

如有任何建议,我们将不胜感激

以下是模型来源:

typedef QHash<QString, uint> Data;

class NewModel : public QAbstractListModel {
    Q_OBJECT
    Q_PROPERTY(int count READ count NOTIFY countChanged)

public:
    NewModel(QObject * parent = 0) : QAbstractListModel(parent) {}

    enum Roles {WordRole = Qt::UserRole, CountRole};

    QHash<int, QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        roles[WordRole] = "word";
        roles[CountRole] = "count";
        return roles;
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
        if (index.row() < 0 || index.row() >= m_data.size()) return QVariant();
        Data::const_iterator iter = m_data.constBegin() + index.row();

        switch (role) {
        case WordRole:
            return iter.key();
        case CountRole:
            return iter.value();
        } return QVariant();
    }

    int rowCount(const QModelIndex &parent) const {
        Q_UNUSED(parent)
        return m_data.size();
    }

    int count() const { return m_data.size(); }

public slots:
    void append(const QString &word) {
        bool alreadyThere = m_data.contains(word);
        if (alreadyThere) m_data[word]++;
        else m_data.insert(word, 1);

        Data::const_iterator iter = m_data.find(word);
        uint position = delta(iter);

        if (alreadyThere) {
            QModelIndex index = createIndex(position, 0);
            emit dataChanged(index, index);
        } else {
            beginInsertRows(QModelIndex(), position, position);
            endInsertRows();
            emit countChanged();
        }
    }

    void prepend(const QString &word) {
        if (m_data.contains(word)) m_data[word]++;
        else m_data.insert(word, 1);
    }

signals:
    void countChanged();

private:
    uint delta(Data::const_iterator i) {
        uint d = 0;
        while (i != m_data.constBegin()) { ++d; --i; }
        return d;
    }

    Data m_data;
};
typedef-QHash数据;
类NewModel:publicQabstractListModel{
Q_对象
Q_属性(整数计数读取计数通知计数已更改)
公众:
NewModel(QObject*parent=0):QAbstractListModel(parent){}
枚举角色{WordRole=Qt::UserRole,CountRole};
QHash roleNames()常量{
QHash角色;
角色[WordRole]=“单词”;
角色[CountRole]=“count”;
返回角色;
}
QVariant数据(常量QModelIndex&index,int-role=Qt::DisplayRole)常量{
if(index.row()<0 | | index.row()>=m|u data.size())返回QVariant();
Data::const_迭代器iter=m_Data.constBegin()+index.row();
交换机(角色){
案例角色:
返回iter.key();
案例角色:
返回iter.value();
}返回QVariant();
}
int行计数(常量QModelIndex和父级)常量{
Q_未使用(家长)
返回m_data.size();
}
int count()常量{返回m_data.size();}
公众时段:
void append(常量QString和word){
bool alreadyThere=m_data.contains(word);
如果(已存在)m_数据[字]+;
else m_数据。插入(字,1);
Data::const_迭代器iter=m_Data.find(word);
uint位置=δ(iter);
如果(已在此处){
QModelIndex index=createIndex(位置,0);
发出数据更改(索引,索引);
}否则{
beginInsertRows(QModelIndex(),位置,位置);
endInsertRows();
emit countChanged();
}
}
无效预结束(常量字符串和单词){
如果(m_data.contains(word))m_data[word]+;
else m_数据。插入(字,1);
}
信号:
void countChanged();
私人:
uint delta(数据::常量迭代器i){
uint d=0;
而(i!=m_data.constBegin()){++d;--i;}
返回d;
}
数据mu数据;
};
下面是“尝试”排序:

NewModel model;
QAbstractItemModel * pm = qobject_cast<QAbstractItemModel *>(&model);
QSortFilterProxyModel proxy;
proxy.setSourceModel(pm);
proxy.setSortRole(NewModel::WordRole);
proxy.setDynamicSortFilter(true);
NewModel;
QAbstracteModel*pm=QoObject_cast(&model);
QSortFilterProxy模型代理;
委托书:setSourceModel(pm);
setSortRole(NewModel::WordRole);
setDynamicSortFilter(true);

唉,代理作为一个模型工作,但它不会对条目进行排序。

首先,不需要
qobject\u cast
向下转换--
NewModel
qabstractemmodel
的派生类,多态性原则表示可以在父类适用的任何地方使用子类

其次,您的
prepend
方法不使用
beginInsertRows
endInsertRows
。这违反了MVCAPI。如果这样使用,附加视图和代理模型中的数据将损坏

第三,您没有提到是否实际使用代理模型作为附加视图的模型:)


最后,使用
QHash
作为数据的后备存储,并使用
QHash::iterator
进行插入。这是一个IT测试解决方案,但有些东西无法工作——插入或删除会导致哈希表增长/收缩,这意味着更改通过模型索引发布的所有数据。这是行不通的。当您需要稳定的订单时,不要使用
QHash
。您的
delta
方法的
O(n)
复杂性应解释为警告;这是一种错误的方法。

如果启用QSortFilterProxyModel::setDynamicSortFilter(true),则需要调用QSortFilterProxyModel::sort(…)函数一次,以让代理知道排序的方式

这样,每当模型更新时,代理都会自动对所有内容重新排序

proxy.setDynamicSortFilter(true);
proxy.sort(0);

看一看。该项目将QSortFilterProxyModel的功能很好地公开给QML。我在不同的项目中使用了它,而且效果很好。然而,如果你想实现你自己的解决方案,那就需要得到你的想法

prepend()
用于填充未使用的模型,明智地使用它没有问题。我需要使用QHash进行查找,我已经使用hash进行了存储,然后将数据传输到另一个模型,但是我正在寻找重用hash中原始数据的方法。该模型看起来工作正常,我的问题只是排序。尝试在代码之上运行ModelTest,您可能会感到惊讶。它是在严格指定的上下文中使用的,认为它作为整个API的一部分是完美的想法相去甚远,我只针对我特别需要的功能。也许这就是为什么它不能与排序代理一起工作。做我自己的排序代理包装比让stock-one与模型一起工作更容易,同时保持底层容器的优化以实现最快的查找,这是N1的要求。