avb*_*avb 11 qt qabstractitemmodel qml qt-quick qtquick2
我想在QML中使用QAbstractListModel派生模型.将模型绑定到视图已经很有效.
我想要实现的下一件事是能够访问特定项目及其角色,就像使用QML ListModel一样
grid.model.get(index).DisplayRole
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何在我的QAbstractListModel派生模型中实现这个get方法.
任何提示?
小智 20
您可以将Q_INVOKABLE函数添加到QAbstractItemModel派生类,如下所示:
...
Q_INVOKABLE QVariantMap get(int row);
...
QVariantMap get(int row) {
QHash<int,QByteArray> names = roleNames();
QHashIterator<int, QByteArray> i(names);
QVariantMap res;
while (i.hasNext()) {
i.next();
QModelIndex idx = index(row, 0);
QVariant data = idx.data(i.key());
res[i.value()] = data;
//cout << i.key() << ": " << i.value() << endl;
}
return res;
}
Run Code Online (Sandbox Code Playgroud)
这将返回类似的内容{ "bookTitle" : QVariant("Bible"), "year" : QVariant(-2000) },你可以使用.bookTitle
Xan*_*der 13
如果你想在列表模型中使用经典的角色方法,你不必在c ++方面做任何特殊的事情,你总是有你的模型,它应该实现数据方法:
QVariant QAbstractItemModel::data(const QModelIndex & index, int role = Qt::DisplayRole) const
Run Code Online (Sandbox Code Playgroud)
要从QML访问不同的角色,model可以在ListView委托中使用附加属性:
model.display // model.data(index, Qt::DisplayRole) in c++
model.decoration // Qt::DecorationRole
model.edit // Qt::EditRole
model.toolTip // Qt::ToolTipRole
// ... same for the other roles
Run Code Online (Sandbox Code Playgroud)
我认为Qt doc中尚未记录到这一点,但是为了找出可以从QML访问的属性,只需在调试模式下启动应用程序并在委托中放置断点或将所有属性打印到控制台.Btw model委托内的属性是QQmlDMAbstractItemModelData类型,所以在后台发生了一些"Qt魔法",看起来像列表模型数据的一些包装,我仍然在Qt文档中找不到任何关于那个的官方(我想)我自己用QML调试器和东西).
如果您需要从代理外部访问模型数据,我认为没有任何内置功能,因此您必须自己执行此操作.
我为自定义QAbstractListModel类做了一个示例,该类公开了一个类似于默认QML ListModel 的count属性和get函数:
mylistmodel.h
class MyListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit MyListModel(QObject *parent = 0);
int rowCount(const QModelIndex & = QModelIndex()) const override { return m_data.count(); }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE int get(int index) const { return m_data.at(index); }
signals:
void countChanged(int c);
private:
QList<int> m_data;
};
Run Code Online (Sandbox Code Playgroud)
mylistmodel.cpp
MyListModel::MyListModel(QObject *parent) :
QAbstractListModel(parent)
{
m_data << 1 << 2 << 3 << 4 << 5; // test data
emit countChanged(rowCount());
}
QVariant MyListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
return QVariant();
int val = m_data.at(index.row());
switch (role) {
case Qt::DisplayRole:
return QString("data = %1").arg(val);
break;
case Qt::DecorationRole:
return QColor(val & 0x1 ? Qt::red : Qt::green);
break;
case Qt::EditRole:
return QString::number(val);
break;
default:
return QVariant();
}
}
Run Code Online (Sandbox Code Playgroud)
由于很容易向QML公开属性和函数,我想这是一个很好的方法来做知道.
为了完整性,这里使用我的自定义模型的ListView示例:
ListView {
anchors.fill: parent
model: MyListModel { id: myModel }
delegate: Text {
text: model.display
}
Component.onCompleted: {
console.log(myModel.count) // 5
console.log(myModel.get(0)) // 1
}
}
Run Code Online (Sandbox Code Playgroud)