Russian Qt Forum
Ноябрь 23, 2024, 03:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Обновление данных view при обновлении модели  (Прочитано 3694 раз)
tyorn
Гость
« : Август 21, 2015, 11:31 »

Собственно модель - наследник QAbstractListModel, представление - GridView. Проблема в том, что по doubleClick на элементе я должен изменить текст внутри него. относительно документации реализовал в наследнике setData и flags, при доблклике в модели проиходит обновление значения по роли, но обратно представление его уже не получает. хотя явный вызов dataChanged присутствует, т.е. не срабатвает привязка что-ли. ниже код

@audioTrackSetupModel.h
Код:
#ifndef AUDIOTRACKSETUPMODEL_H
#define AUDIOTRACKSETUPMODEL_H

#include <QObject>
#include <QAbstractListModel>
#include <QList>
#include <QVariant>
#include <QMetaType>

class AudioTrackItem : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
    Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
    AudioTrackItem(QString text = "", bool selected = false, bool enabled = false, QObject *parent = 0);

    QString text() const;
    void setText(QString text);

    bool selected() const;
    void setSelected(bool value);

    bool enabled() const;
    void setEnabled(bool state);


signals:
    void textChanged();
    void selectedChanged();
    void enabledChanged();

private:
    QString m_text;
    bool m_selected;
    bool m_enabled;
};

class AudioTrackSetupModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum ATSRItemRoles
    {
        TextRole = Qt::UserRole + 1,
        SelectedRole,
        LabelsRole
    };
    AudioTrackSetupModel(QObject *parent = 0);

    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::DisplayRole);
    Qt::ItemFlags flags(const QModelIndex &index) const;

    void initGrid();

public slots:
    QList<QVariant> chLabels() const;
    bool isInSelection(QVariant index) const;


private:
    QList<AudioTrackItem* > m_items;
    QHash<int, QByteArray> roleNames() const;
    int m_selectedRow;
};


#endif // AUDIOTRACKSETUPMODEL_H

@audioTrackSetupModel.cpp
Код:
#include "audiotracksetupmodel.h"
#include <QDebug>

AudioTrackItem::AudioTrackItem(QString text, bool selected, bool enabled, QObject *parent)
    : QObject(parent),
      m_text(text),
      m_selected(selected),
      m_enabled(enabled)
{

}

QString AudioTrackItem::text() const
{
    return m_text;
}

void AudioTrackItem::setText(QString text)
{
    if (m_text != text)
    {
        m_text = text;
        emit textChanged();
    }
}

bool AudioTrackItem::selected() const
{
    return m_selected;
}

void AudioTrackItem::setSelected(bool value)
{
    if (m_selected != value)
    {
        m_selected = value;
        emit selectedChanged();
    }
}

bool AudioTrackItem::enabled() const
{
    return m_enabled;
}

void AudioTrackItem::setEnabled(bool state)
{
    if (m_enabled != state)
    {
        m_enabled = state;
        emit enabledChanged();
    }
}

AudioTrackSetupModel::AudioTrackSetupModel(QObject *parent)
    : QAbstractListModel(parent),
      m_selectedRow(-1)
{

}

int AudioTrackSetupModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_items.count();
    //    return 1024; // 32 ch * 32 ch
}

QHash<int, QByteArray> AudioTrackSetupModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[TextRole] = "text";
    roles[SelectedRole] = "selected";
    roles[LabelsRole] = "labels";
    return roles;
}

QVariant AudioTrackSetupModel::data(const QModelIndex &index, int role) const
{

    if (role == TextRole)
    {
        return m_items[index.row()] -> text();
    }
    if (role == SelectedRole)
    {
        return m_items[index.row()] -> selected();
    }
    if (role == LabelsRole)
    {
        return chLabels();
    }
    return QVariant();
}

void AudioTrackSetupModel::initGrid()
{
    for (int i = 0; i < 1024; ++i)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_items.append(new AudioTrackItem);
        endInsertRows();
    }
}

Qt::ItemFlags AudioTrackSetupModel::flags(const QModelIndex &index) const
{
    return (QAbstractListModel::flags(index)|Qt::ItemIsEditable);
}

bool AudioTrackSetupModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role == TextRole)
    {
        qDebug()<<index.row();
        m_items[index.row()] -> setText(value.toString());
        qDebug()<<m_items[index.row()]->text();
        //emit dataChanged(QAbstractListModel::createIndex(index.row(), 0), QAbstractListModel::createIndex(index.row(), 0));
        emit dataChanged(QAbstractListModel::createIndex(0, 0), QAbstractListModel::createIndex(1024, 0));
        return true;
    }
    if (role == SelectedRole)
    {
        if (m_selectedRow != index.row() / 32)
        {
            if (m_selectedRow >= 0)
            {
                for (int i = m_selectedRow * 32; i < (m_selectedRow + 1) * 32; ++i)
                    m_items[i] -> setSelected(false);
                emit dataChanged(QAbstractListModel::createIndex(m_selectedRow * 32, 0), QAbstractListModel::createIndex((m_selectedRow + 1) * 32, 0));
            }
            m_selectedRow =  index.row() / 32;
            for (int i = m_selectedRow * 32; i < (m_selectedRow + 1) * 32; ++i)
                m_items[i] -> setSelected(value.toBool());
            emit dataChanged(QAbstractListModel::createIndex(m_selectedRow * 32, 0), QAbstractListModel::createIndex((m_selectedRow + 1) * 32, 0));
            //emit dataChanged(QAbstractListModel::createIndex(0, 0), QAbstractListModel::createIndex(1024, 0));
            return true;
        }
    }
    return false;
}

QList<QVariant> AudioTrackSetupModel::chLabels() const
{
    QList<QVariant> tl;
    for (int i = 0; i < 32; ++i)
    {
        tl<<QVariant::fromValue(i + 1);
    }
    return tl;
}

bool AudioTrackSetupModel::isInSelection(QVariant index) const
{
    return index.toInt() == m_selectedRow;
}

@main.qml
Код:
import QtQuick 2.0
import "Style.js" as S

Rectangle {
    width: 800
    height: 800

    property int gridItemWidth: 20
    property int gridItemHeight: 15
    property int marginSize: 1
    color: S.blueBackgroundColor

    GridView {
        id: grid
        width: 32 * gridItemWidth
        height: 32 * gridItemHeight
        model: atm
        cellWidth: gridItemWidth
        cellHeight: gridItemHeight

        header: chLabels
        footer: chLabels

        Component {
            id: chLabels
            Rectangle {
                width: grid.width - 2 * marginSize
                height: gridItemHeight - 2 * marginSize
                color: "transparent"

                ListView {
                    width: parent.width
                    height: parent.height
                    model: atm.chLabels() //labels
                    orientation: ListView.Horizontal
                    delegate: Rectangle {
                        width: gridItemWidth
                        height: gridItemHeight
                        color: "transparent"
                        Text {
                            text: modelData// + 1
                            color: modelData === 5 ? S.yellowColor : S.orangeColor
                            anchors.centerIn: parent
                        }
                    }
                }
            }
        }



        delegate: Rectangle {
            width: gridItemWidth - 2 * marginSize
            height: gridItemHeight - 2 * marginSize
            color: S.blueBackgroundColor

            border {
                width: 1
                color: selected ? S.yellowColor :S.blueColor
            }

            Rectangle {
                width: parent.width - 2 * parent.border.width
                height: parent.height - 2 * parent.border.width
                anchors.centerIn: parent

                color: selected ? S.yellowColor : S.blueBackgroundColor
                opacity: text === "" && selected ? 0.25 : 1

                Text {
                    id: textBox1
                    text: text
                    color: S.blackColor
                    font.pixelSize: S.mediumTextSize - 1
                    anchors.centerIn: parent
                    //z: 1
                }
            }

            MouseArea {
                anchors.fill: parent

                onClicked: {
                    selected = !selected
                    console.log("qml:", text)
                    console.log("textBox1", textBox1.text)
                }

                onDoubleClicked: {
                    text = "5"
                    //textBox1.text = "5"
                }
            }
        }
    }

}

@main.cpp
Код:
#include <QGuiApplication>
#include <QQuickView>
#include <QQmlContext>
#include <QDebug>

#include "audiotracksetupmodel.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQuickView view;

    AudioTrackSetupModel atm;
    atm.initGrid();

    view.rootContext()->setContextProperty("atm", &atm);

    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();

    return app.exec();
}

Вывод вот этих значений
Код:
                    console.log("qml:", text)
                    console.log("textBox1", textBox1.text)
показывает как раз, что в модели значение изменилось, qml его успешно читает при этом как новое, в то же время не изменилось значение текста для textBox1, хотя его значение это же вроде как привязка по роли:
Text {
                    id: textBox1
                    text: text
...
« Последнее редактирование: Август 21, 2015, 12:35 от Пантер » Записан
tyorn
Гость
« Ответ #1 : Август 21, 2015, 11:44 »

Upd: назвать роль именем свойства компонента было плохой идеей. собственно только в этом и проблема. к сожалению, тему удалить / закрыть не могу
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #2 : Август 21, 2015, 12:35 »

Удалять не нужно, отметил как решенную. Вдруг, кто еще напорется.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.057 секунд. Запросов: 23.