如何从QAbstractListModel返回自定义QObject子类并在QML ListView中使用它。
我试图将对象作为显示角色返回,我在qml display.property中使用来访问属性,它工作正常但我在一些帖子中看到人们使用model作为qml的qobject并访问属性作为model.property。我错过了什么吗?。
另一个问题:如果我想在ListView级别公开对象并使用它来设置一些其他面板,如主视图细节,则将角色(在我的情况下显示)公开为委托和设置中的variant属性在listview级别使用onCurrentItemChanged信号是正确的方法吗?
这是我正在尝试的但它不起作用:
#ifndef NOTE_H
#define NOTE_H
#include <QObject>
class Note : public QObject
{
Q_OBJECT
Q_PROPERTY(QString note READ note WRITE setNote NOTIFY noteChanged)
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
QString m_note;
int m_id;
public:
explicit Note(QObject *parent = 0);
Note(QString note, int id, QObject *parent = 0);
QString note() const
{
return m_note;
}
int id() const
{
return m_id;
}
signals:
void noteChanged(QString note);
void idChanged(int id);
public slots:
void setNote(QString note)
{
if (m_note == note)
return;
m_note = note;
emit noteChanged(note);
}
void setId(int id)
{
if (m_id == id)
return;
m_id = id;
emit idChanged(id);
}
};
#endif // NOTE_H
视图模型:
#ifndef NOTESVIEWMODEL_H
#define NOTESVIEWMODEL_H
#include <QAbstractListModel>
#include <QVector>
#include "note.h"
class NotesViewModel : public QAbstractListModel
{
Q_OBJECT
QVector<Note*> notes;
public:
NotesViewModel();
QVariant data(const QModelIndex &index, int role) const override;
int rowCount(const QModelIndex &parent) const override;
};
#endif // NOTESVIEWMODEL_H
视图模型的实现:
NotesViewModel::NotesViewModel()
{
notes.append(new Note("note 1", 1));
notes.append(new Note("note 2", 2));
notes.append(new Note("note 3", 3));
notes.append(new Note("note 4", 4));
notes.append(new Note("note 5", 5));
}
QVariant NotesViewModel::data(const QModelIndex &index, int role) const
{
qDebug() << "fetching data : " << index.row();
if(!index.isValid()) return QVariant();
if(index.row() >= 5) return QVariant();
if(role == Qt::DisplayRole)
return QVariant::fromValue(notes[index.row()]);
return QVariant();
}
int NotesViewModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return notes.count();
}
答案 0 :(得分:2)
由于您已经回答了第二个问题,请让我接受第一个问题,即display.propertyName
vs model.propertyName
基本上第一个只是model.display.propertyName
的简写,即&#34;显示&#34;正在访问给定索引处的模型数据的属性。在您的情况下,返回一个对象,该对象的on上有属性。
model.propertyName
也可以写为propertyName
,这意味着模型的数据()方法会被调用&#34; role&#34;是&#34; propertyName&#34;。
来自&#34; propertyName&#34;的映射使用QAbstractItemModel::roleNames()
方法完成其数值等效。
它的默认实现有一些基本映射,例如映射&#34; display&#34;到Qt::DisplayRole
。
答案 1 :(得分:1)
我使用qml ListView尝试了解如何将currentItem数据公开给外部世界。这就是我设法做到的方式,也许它会对像我这样的新手有用。
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ListModel {
id: modell
ListElement {
fname: "houssem"
age: 26
}
ListElement {
fname: "Anna"
age: 26
}
ListElement {
fname: "Nicole"
age: 26
}
ListElement {
fname: "Adam"
age: 27
}
}
ListView {
id: lv
height: 100
width: 200
clip: true
model: modell
property string selectedName: currentItem.name
delegate: Component {
Item {
id: mainItem
width: ListView.view.width
height: 80
property string name: fname
Text {
text: "name " + fname + " age " + age
}
MouseArea {
anchors.fill: parent
onClicked: mainItem.ListView.view.currentIndex = index
}
}
}
}
Text {
anchors.right: parent.right
text: lv.selectedName
}
}
正如您在代码中看到的那样,为了公开currentItem的数据,我只需要在委托Item中声明属性(在本示例中为string类型的name属性),然后绑定ListView上的属性(本例中为selectedName) )对于currentItem.property,这样当我从列表中选择其他项目时,ListView上的属性将自动更新,我将可以从UI的其他项目访问这些项目。