如何更新Qml列表视图中的值?

时间:2013-06-14 00:19:13

标签: qt listview qml qtquick2

我有一个ListModel,它存储字符串“cityName”和实际值“TimeZoneOffset”。顾名思义,cityName保存城市名称,TimeZoneOffset保存时间偏移量(从UTC开始),以分钟为单位。

ListModel {
  id: worldCity

  ListElement {
   cityName: "London"
   TimeZoneOffset: 0
  }

  ListElement {
   cityName: "Amsterdam"
   TimeZoneOffset: 120
  }
}

然后在ListView中使用此模型。 ListView的结构如下面的代码示例所示。

ListView {
  model: worldCity
  currentIndex: -1

  delegate: ListItem.Standard {
    text: cityName        
    Label {
      text: timeOffSet + currentSystemTime
    }
  }
}

如您所见,我的ListView显示修改后的输出,而不是直接输出listModel元素。我需要每分钟更新ListView元素以显示城市的当前时间。我打算每分钟使用一个Timer来更新它。

如何更新每个listView元素?

3 个答案:

答案 0 :(得分:5)

对我来说,直接更新模型似乎不是正确的选择,这里是一个简化的增强版代码,可以做正确的事情:

import QtQuick 2.0

Rectangle {
    width: 200;
    height: 400;

    property real currentTimestamp;

    function updateTime () {
        var now = new Date ();
        currentTimestamp = now.getTime ();
    }

    Timer {
        interval: 60000;
        repeat: true;
        running: true;
        onTriggered: { updateTime (); }
    }
    ListView {
        anchors.fill: parent;
        model: ListModel {
            ListElement { cityName: "London";     timeOffSet: 0;   }
            ListElement { cityName: "Amsterdam";  timeOffSet: 120; }
            ListElement { cityName: "Paris";      timeOffSet: 60;  }
        }
        delegate: Column {
            anchors {
                left: parent.left;
                right: parent.right;
            }

            Text {
                text: model.cityName;
                font.bold: true;
            }
            Text {
                text: Qt.formatTime (new Date (currentTimestamp + (model.timeOffSet * 60000)), "hh:mm A");
            }
        }
    }
    Component.onCompleted: { updateTime (); }
}

答案 1 :(得分:0)

QML ListModel对于脚本编写非常没有文档,但是查看它的源代码,可以知道哪些方法可以迭代。

如果您正在使用某些JSON API并且需要内联更新对象,或者如果您无法直接访问ListElement,那么这些是您可以通过脚本从模型中访问的方法:

Q_INVOKABLE void clear();
Q_INVOKABLE void remove(int index);
Q_INVOKABLE void append(const QScriptValue&);
Q_INVOKABLE void insert(int index, const QScriptValue&);
Q_INVOKABLE QScriptValue get(int index) const;
Q_INVOKABLE void set(int index, const QScriptValue&);
Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
Q_INVOKABLE void move(int from, int to, int count);
Q_INVOKABLE void sync();

答案 2 :(得分:0)

我更喜欢将模型保留在C ++,Qt端。所以使用所有的proxymodel东西是可行的。在Qt上,你必须将C ++对象m_pMyModel设置为QML世界的属性:

m_pQuickView->rootContext()->setContextProperty("_myModel", m_pMyModel);

并在QML中直接使用它:

    ListView {
            id: listView
            model : _myModel
            delegate : myDelegate
            ....
   }

为了能够在QML委托中使用数据,您必须创建一个roleNames哈希:

 QHash<int, QByteArray> MyModel::roleNames() const
  {
    QHash<int, QByteArray> roles;
    roles[NameRole] = "name_role";
    roles[IconRole] = "icon_role";
    roles[StateRole] = "state_role";
    roles[TypeRole] = "type_role";
    return roles;
}