从Qml更改c ++ QAbstractListModel值

时间:2017-09-26 20:00:54

标签: qt qml

这是我的代码

devicemodel.h

class Device
{
public:
    Device(const int &nodeId ,const QString &type, const int &lampVoltage);
//![0]

    QString type() const;
    int lampVoltage() const;
    int nodeId() const;
public:
    QString m_type;
    int m_lampVoltage;
    int m_nodeId;
//![1]


};

class DeviceModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum DeviceRoles {
        NodeIdRole = Qt::UserRole + 1,
        TypeRole ,
        LampVoltageRole

    };

    DeviceModel(QObject *parent = 0);
//![1]

    void addDevice(const Device &Device);

    int rowCount(const QModelIndex & parent = QModelIndex()) const;

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;

protected:
    QHash<int, QByteArray> roleNames() const;
private:
    QList<Device> m_Devices;
//![2]

public slots :
    void callFromQml(int index);

};

devicemodel.cpp

Device::Device(const int &nodeId ,const QString &type, const int &lampVoltage)
    : m_nodeId(nodeId) , m_type(type), m_lampVoltage(lampVoltage)
{
}

QString Device::type() const
{
    return m_type;
}

int Device::nodeId() const
{
    return m_nodeId;
}

int Device::lampVoltage() const
{
    return m_lampVoltage;
}

DeviceModel::DeviceModel(QObject *parent)
    : QAbstractListModel(parent)
{
}



void DeviceModel::callFromQml(int index){

   Device k= m_Devices.at(index);
   qDebug() << k.type() << k.lampVoltage();
   k.m_lampVoltage = 5;
    emit dataChanged(createIndex(index,0), createIndex(index,0), {0,1,2} );
}

void DeviceModel::addDevice(const Device &Device)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_Devices << Device;
    endInsertRows();
}

int DeviceModel::rowCount(const QModelIndex & parent) const {
    Q_UNUSED(parent);
    return m_Devices.count();
}

QVariant DeviceModel::data(const QModelIndex & index, int role) const {
    if (index.row() < 0 || index.row() >= m_Devices.count())
        return QVariant();

    const Device &Device = m_Devices[index.row()];
    if (role == NodeIdRole)
        return Device.nodeId();
    else if (role == TypeRole)
        return Device.type();
    else if (role == LampVoltageRole)
        return Device.lampVoltage();
    return QVariant();
}

//![0]
QHash<int, QByteArray> DeviceModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[NodeIdRole] = "nodeId";
    roles[TypeRole] = "type";
    roles[LampVoltageRole] = "lampVoltage";
    return roles;
}

main.qml

ListView {
    width: 200; height: 250
    spacing: 10
    model: myModel
    delegate:
        Text { text: "Animal: " + type + ", " + lampVoltage

        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log("egwegweg");
                myModel.callFromQml(index);
                //lampVoltage = 10;

               // myModel.setData(index , 10 , 2);
            }
        }
    }
}

的main.cpp

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    DeviceModel model;
    model.addDevice(Device(1, "Medium" , 200));
    model.addDevice(Device(1, "Medium" , 200));
    model.addDevice(Device(1, "Medium" , 200));
    QQmlContext *ctxt = engine.rootContext();
    ctxt->setContextProperty("myModel", &model);
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    model.addDevice(Device(1, "Medium" , 200));
    model.addDevice(Device(1, "Medium" , 200));
    model.addDevice(Device(1, "Medium" , 200));

    return app.exec();

我想从Qml修改我的项目值 我写了一个名为callFromQml的插槽,并将项目索引从qml传递给c ++代码,并希望从中更新值 但不能这样做 我不知道发射信号是否有效,并且不知道是否正确传递指数而且不能

1 个答案:

答案 0 :(得分:1)

感谢 @MarkCh 指出,您尚未重新实现setData()-method

签名是:

bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)

如果成功设置了一些数据,则返回true,如果没有,则返回false。 此外,uppon成功,在返回之前,有必要emit dataChanged(...)所以任何观点都会意识到这一变化。

我们这样做:

  1. 将相应的声明添加到头文件
  2. 将实施添加到.cpp - 文件中。这可能如下所示:
  3. bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.row() < 0 || index.row() >= m_Devices.count())
            return false;
    
        const Device &Device = m_Devices[index.row()];
        if (role == NodeIdRole) {
            Device.m_nodeId = value.toInt();
            emit dataChanged(index, index);
            return true;
        }
        else if (role == TypeRole) {
            Device.m_type = value.toString();
            emit dataChanged(index, index);
            return true;
        }
        else if (role == LampVoltageRole) {
            Device.m_lampVoltage = value.toInt();
            emit dataChanged(index, index);
            return true;
        }
        return false;
    }
    
    1. DeviceModel设为friend Device或将私有字段的访问权限更改为使用getter。如你所愿。
    2. 现在您应该能够在委托中设置角色,就像它们是属性一样......赞:

      onClicked: model.nodeId = 100;
      
        

      上述代码未经过测试,但应包含最相关的详细信息。