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

Qml listview add new row to a sub vector in the model

本文关键字:向量 模型 ListView 新行 添加 QML      更新时间:2023-10-16

我在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();
}

前两个连接函数正常工作,用于插入新项目,但第二个连接函数失败。

将信号连接到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 by 1 by 1。



添加自定义对象示例:

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_;
};