Ed *_*Nio 6 qt qabstractitemmodel qml qt-quick
我使用Qt example for QAbstractItemModel并尝试将 更新为Item给定的index.
我尝试使用emit DataChanged但它不起作用,视图未更新。
下面是一个例子:
我想什么:当你点击按钮,它会在索引0更新数据,该type动物将被改变,它会成为一个狮子。
#include <QAbstractListModel>
#include <QStringList>
#include <qqmlcontext.h>
//![0]
class Animal
{
public:
Animal(const QString &type, const QString &size);
//![0]
QString type() const;
QString size() const;
void setType(QString q) {
m_type = q;
}
private:
QString m_type;
QString m_size;
//![1]
};
class AnimalModel : public QAbstractListModel
{
Q_OBJECT
public:
Q_INVOKABLE void test() ;
void setName(const QString &name);
enum AnimalRoles {
TypeRole = Qt::UserRole + 1,
SizeRole
};
AnimalModel(QObject *parent = 0);
//![1]
//!
//!
void setContext(QQmlContext *ctx) {
m_ctx = ctx;
}
void addAnimal(const Animal &animal);
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
QHash<int, QByteArray> roleNames() const;
protected:
private:
QList<Animal> m_animals;
QQmlContext* m_ctx;
signals:
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
//![2]
};
//![2]
Run Code Online (Sandbox Code Playgroud)
模型.h
#include "model.h"
#include "qDebug"
Animal::Animal(const QString &type, const QString &size)
: m_type(type), m_size(size)
{
}
QString Animal::type() const
{
return m_type;
}
QString Animal::size() const
{
return m_size;
}
AnimalModel::AnimalModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void AnimalModel::addAnimal(const Animal &animal)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_animals << animal;
endInsertRows();
}
void AnimalModel::test() {
m_animals[0].setType("Lion");
emit dataChanged(QModelIndex(),QModelIndex());
//I also tried:
QModelIndex topLeft = createIndex(0,0);
emit dataChanged(topLeft, topLeft);
}
int AnimalModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_animals.count();
}
QVariant AnimalModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_animals.count())
return QVariant();
const Animal &animal = m_animals[index.row()];
if (role == TypeRole)
return animal.type();
else if (role == SizeRole)
return animal.size();
return QVariant();
}
//![0]
QHash<int, QByteArray> AnimalModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[TypeRole] = "type";
roles[SizeRole] = "size";
return roles;
}
//![0]
Run Code Online (Sandbox Code Playgroud)
模型.cpp
#include "model.h"
#include <QGuiApplication>
#include <qqmlengine.h>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
//![0]
int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
AnimalModel model;
model.addAnimal(Animal("Wolf", "Medium"));
model.addAnimal(Animal("Polar bear", "Large"));
model.addAnimal(Animal("Quoll", "Small"));
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
//![0]
view.setSource(QUrl("qrc:view.qml"));
view.show();
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
主程序
import QtQuick 2.0
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QtQml.Models 2.1
import QtQuick.Controls.Styles 1.2
//![0]
ListView {
width: 200; height: 250
model: myModel
delegate: Text { text: "Animal: " + type + ", " + size }
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
}
}
Button {
anchors.bottom: parent.bottom
width:50; height:50
text:"click"
onClicked: {
myModel.test()
}
}
}
//![0]
Run Code Online (Sandbox Code Playgroud)
查看.qml
你知道为什么它不起作用吗?非常感谢 !
不要在子类中重新定义信号。
删除以下几行(在 model.h 中),它应该按预期工作:
signals:
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
Run Code Online (Sandbox Code Playgroud)
此外,这在调用时dataChanged()您必须指定一个有效的QModelIndex. 这是对的 :
// I also tried:
QModelIndex topLeft = createIndex(0,0);
emit dataChanged(topLeft, topLeft);
Run Code Online (Sandbox Code Playgroud)