LINUX.ORG.RU

qt. наследование qasbtractlistmodel для qml

 , ,


0

2

Решил, раз под наркотиками, можно написать одноранговый чат на qt/qml. Вроде как и не первый год на qt, но какого лешего не вызывается метод data()? Для простоты можно представить, что rowCount() возвращает всегда 1, в data() возвращается всегда QVariant().


#pragma once

#include <QAbstractListModel>

#include "jsonpacket.h"

class MessagesModel : public QAbstractListModel
{
	Q_OBJECT

public:
	MessagesModel();
	MessagesModel(const MessagesModel &other);

public:
	Q_INVOKABLE virtual QVariant data(
			const QModelIndex &index,
			int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
	Q_INVOKABLE virtual int rowCount(
			const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;

protected:
	QList<MessagePacket> m_messages;
};

Q_DECLARE_METATYPE(MessagesModel)

но какого лешего не вызывается метод data()

Не вижу вызов метода data. Предлагаешь гадать по хидеру?

ox55ff ★★★★★ ()
Ответ на: комментарий от Torvus

для QAbstractItemModel и иже с ними вроде как бы и так, но

«If your model is used within QML and requires roles other than the default ones provided by the roleNames() function, you must override it.»

А т.к. я на все вообще роли отдаю мой объект (да даже если только на DisplayRole), это всё равно не важно, т.к. отладчик не заходит в data()

luntik2012 ()
Ответ на: комментарий от ox55ff

вызываться он должен из ListView из qml.

после региастрации модели навроде такого

engine.rootContext()->setContextProperty(«messagesModel», new MessagesModel());

имею ListView такой

ListView { anchors.fill: parent

model: messagesModel

delegate: ItemDelegate { text: text width: parent.width } }

Если что, у объекта единственный Q_PROPERTY text, но мне даже не интересно, перекрывает ли он свойство text от ItemDelegate.

luntik2012 ()
Ответ на: комментарий от ox55ff

вообще хотел выкинуть весь проект куда-нибудь, но на гитхаб ведь не положишь, там тупо демка в пару строк. куда можно положить такое, чтобы с отступами и все дела?

luntik2012 ()

Метод QVariant data() не нужно отмечать макросом Q_INVOKABLE, он уже таков. Вызывается когда проперти в QML присваиваешь значение определенной в модели роли.

Liferer ()

Покажи код QML и определение MessagesModel::data()

equeim ★★ ()
Ответ на: комментарий от luntik2012

Должно быть примерно так:



class MessagesModel : public QAbstractListModel
{
    Q_OBJECT
public:
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;

protected:
    QHash<int, QByteArray> roleNames() const override;

    QList<MessagePacket> m_messages;
};

QVariant data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return;
    }

    if (role == Qt::UserRole) {
        return m_messages[index.row()].name();
    }

    return QVariant();
}

int rowCount(const QModelIndex&) const
{
    return m_messages.size();
}

QHash<int, QByteArray> roleNames() const
{
    return {{Qt::UserRole, "name"}};
}

В QML внутри делегата получаешь значение как modelData.name (или model.name). Если ролей нужно нескольно, то соответственно меняешь data() и roleNames(). Все роли должны начинаться с Qt::UserRole (хотя в данном случае она одна, и можно использовать и стандартную Qt::DisplayRole).

equeim ★★ ()
Последнее исправление: equeim (всего исправлений: 2)
Ответ на: комментарий от luntik2012

delegate: ItemDelegate { text: text width: parent.width } }

возможно,

delegate: ItemDelegate { text: modelData.text width: parent.width } }

unC0Rr ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.