Qml ListView将新行添加到模型中的子向量

时间:2019-05-21 10:26:01

标签: c++ qt qml

我有一个用C ++定义的自定义结构,其中包含几个变量,其中一个是QList变量。我现在可以在Qml listview中动态添加一个新结构,但是我的问题是我也想在该结构内的QList中添加一个新项目,我可以在后台执行此操作,但是无法更新listview。

我认为该错误出现在C ++的connect()函数中。据我了解,要添加新行,需要调用beginInsertRows()和endInsertRows(),但是在这两种情况下发送方和接收方应该相同吗?

所以我在C ++中具有以下结构,以及一些用于插入新行的信号和函数。

“ todolist.h”:

struct ToDoItem
{
    bool done;
    QString description;
    QList<int> list;

    ToDoItem(){
        done = false;
        description = "text";
        QList<int> mylist;
        mylist.append(1);
        list = mylist;
    }
};
signals:
    void preItemAppended();
    void postItemAppended();

    void preListAppended();
    void postListAppended();

public slots:
    void appendItem();
    void appendList();

void ToDoList::appendItem()
{
    emit preItemAppended();

    mItems.append(ToDoItem());
    emit postItemAppended();
}

void ToDoList::appendList()
{
    emit preListAppended();

    mItems[0].list.append(1);

    emit postListAppended();
}

“ todomodel.h”

void ToDoModel::setList(ToDoList *list)
{
    beginResetModel();

    if (mList)
        mList->disconnect(this);

    mList = list;

    if (mList) {
        connect(mList, &ToDoList::preItemAppended, this, [=]() {
            const int index = mList->items().size();
            beginInsertRows(QModelIndex(), index, index);
        });
        connect(mList, &ToDoList::postItemAppended, this, [=]() {
            endInsertRows();
        });

        connect(mList, &ToDoList::preListAppended, this, [=]() {
            const int index = mList->lists().size();
            beginInsertRows(QModelIndex(), index, index);
        });
        connect(mList, &ToDoList::postListAppended, this, [=]() {
            endInsertRows();
        });
    }

    endResetModel();
}

前两个连接功能可以正常工作,该功能可用于插入新项目,但后两个连接功能失败。

1 个答案:

答案 0 :(得分:0)

将信号连接到beginInsertRowsendInsertRows并不是一个好主意。 您应该对此进行抽象,而应连接到addremove方法。 假设您有实现QAbstractListModel的模型类:

class MyListModel : public QAbstractListModel {

  Q_OBJECT
  Q_PROPERTY(int size READ size NOTIFY sizeChanged)

  public:
  explicit myListModel(QObject *parent = nullptr);
  ~myListModel() override;

  int rowCount(const QModelIndex &p) const override;
  QVariant data(const QModelIndex &index, int role) const override;
  QHash<int, QByteArray> roleNames() const override;
  int size() const;

  public slots:
  void add(QObject *o);
  QObject *remove(int i);
  signals:
  void sizeChanged();

 private:
  QList<QObject *> m_data;

};

addremove的实现如下:

void MyListModel::add(QObject* o) {
    int i = m_data.size();
    beginInsertRows(QModelIndex(), i, i);
    m_data.append(o);
    o->setParent(this);
    sizeChanged();
    endInsertRows();
}


QObject * MyListModel::take(int i) {
    if ((i > -1) && (i < m_data.size())) {
        beginRemoveRows(QModelIndex(), i, i);
        QObject * o = m_data.takeAt(i);
        o->setParent(nullptr);
        sizeChanged();
        endRemoveRows();
        return o;
    }
    return nullptr;
}

在这种情况下,您可以对新添加的项目调用add,或者,如果要重新填充列表,则可以清除它并遍历列表,并以1乘1的方式添加它们。
< br /> 添加自定义对象示例:

class ToDoItem : public QObject {
  Q_OBJECT
  Q_PROPERTY(bool done READ done WRITE setDone NOTIFY doneChanged)

  public:
    explicit ToDoItem(QObject* parent = nullptr);
    ~ToDoItem() override;

    bool done() const { return m_done_; }
    void setDone(bool done) { m_done_ = done; emit doneChanged(done); }

  signals:
    void doneChanged(bool);

  private:
    bool m_done_;
};