Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как изменять значения свойств отдельных элементов из QML в модели QABstractListModel?
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Quick
fil265
Решил использовать модель QAbstractListModel в QML. Так вот, насколько я понял, из QML не получится просто изменить значение, присвоив ему новое значение? Пытался переопределить метод QAbstractListModel::flags(), что бы он возвращал всегда Qt::ItemIsEditable, а так же метод setData() для установки значений, но мне все-равно выдается ошибка в js, что невозможно изменить значение свойства, доступного только для чтения.
Так вот, после того, как это не получилось, пришла мысль просто реализовать в своей модели слот на подобие функции setProperty() у ListModel в QML, что бы просто вызывать из делегата этот метод с индексом и назначать устанавливать свойству необходимое значение.
Получилось примерно следующее:
Модель:

    
    #ifndef MODEL_H
    #define MODEL_H
    #include <QAbstractListModel>
    #include <qlist.h>
    #include "IndexingJob.h"
    
    
    QT_BEGIN_NAMESPACE
    class IndexingJob;
    QT_END_NAMESPACE
    
    class Model: public QAbstractListModel
    {
        Q_OBJECT
    public:
    
        enum IndexingJobsRole
        {
            ID = Qt::UserRole + 1,
            NAME
        };
    
        explicit Model(QObject *parent = 0);
        virtual ~Model();
        int rowCount(const QModelIndex &parent = QModelIndex()) const;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
        bool setData ( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
    
    public slots:
        int getRowCount();
        void append(IndexingJob* _phrase);
        bool setProperty(int index, QString propertyName, QVariant propertyValue);
        QString getGraphName(int index){return m_JobsList[index]->getGraphName();};
    
    signals:
        void rowCountChanged();
    
    
    private:
        QList<IndexingJob*> m_JobsList;
        Q_PROPERTY(int currentRowCount READ getRowCount NOTIFY rowCountChanged)
    
    private slots:
    
    
    protected:
    
    };
    #endif // MODEL_H
    
    [i][b]Реализация класса:[/b][/i]
    #include "Model.h"
    #include "IndexingJob.h"
    
    Model::Model(QObject *parent) :
        QAbstractListModel(parent)
    {
        QHash<int, QByteArray> roles;
        roles[ID]             = "ID";
        roles[NAME]    = "graphFileName";
        setRoleNames(roles);
    }
    
    QVariant Model::data(const QModelIndex &index, int role)const
    {
        if (index.row() < 0 || index.row() > m_JobsList.count())
            return QVariant();
    
        switch(role)
        {
            case ID:      return m_JobsList[index.row()]->getID();
            case NAME:    return m_JobsList[index.row()]->getGraphName();
        }
        return QVariant();
    }
    
    bool Model::setData ( const QModelIndex& index, const QVariant& value, int role )
    {
        if (index.row() < 0 || index.row() > m_JobsList.count())
            return false;
        switch(role)
        {
            case ID:             m_JobsList[index.row()]->setID(value.toInt());break;
            caseNAME:            m_JobsList[index.row()]->setGraphName(value.toString());break;
        }
        emit dataChanged(index, index);
        return true;
    }
    
    bool Model::setProperty(int _index, QString propertyName, QVariant propertyValue)
    {
        if(_index > m_JobsList.count() || _index < 0)
            return false;
        int role = roleNames().key(propertyName.toStdString().c_str());
        switch(role)
        {
            case GRAPH_FILE_NAME: return setData(index(_index), propertyValue, GRAPH_FILE_NAME);
        }
    }
    
    int Model::rowCount(const QModelIndex &parent)const
    {
        return m_JobsList.count();
    }
    
    int Model::getRowCount()
    {
        return m_JobsList.count();
    }
    
    void Model::append(IndexingJob* _Job)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_JobsList.append(_Job);
        endInsertRows();
        emit rowCountChanged();
    }
    
    Model::~Model()
    {
    
    }



Дальше в QML-е создаю модель и Repeater для отображения для каждого итема модели

    ...
    ...
    ...
    Model
    {
        id: model
    }
    
    Repeater
    {
        id: repeater
        delegate:
        Item
        {
            anchors.fill: parent
            Text
            {
                anchors.centerIn:   parent
                text:           graphFileName
            }
            MouseArea
            {
                anchors.fill:   parent
                onClicked:  model.setProperty(index, "graphFileName", "Значение")
                            console.log(graphFileName)
                console.log(indexingModel.getGraphName(index))      
            }
        }
    }
    ...
    ...
    ...



Так вот, когда я так делаю, то значение моего параметра изменяется, это видно по тому, что метод getGraphName(index) возвращает уже новое значение. Но вот модель все по-прежнему думает, что значение не изменилось. Вопрос в том, как подать сигнал о том, что данные в модели изменились. Что-то у меня не получается. Хотя, вроде как в методе setData генерирую сигнал dataChanged(index, index); Помогите, пожалуйста, кто знает в чем проблема и как ее решить. Заранее благодарен.
fil265
Вот же - решил проблему. =) Так, как написано здесь все работает. )) Написал одно, а у себя проверял по-другому и, видимо, совсем не правильно проверял. Я не по нажатию на кнопку изменял значение свойства, а при возникновении сигнала Component.onComplited(). Делал я это для того, что бы проверить работоспособность того, что написал. Видимо, порядок вызова не такой, как я думал и получается, что сигнал об изменении свойства в модели не обрабатывается самой моделью при таком раскладе вещей?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.