在不使用就地编辑的情况下更改Qt AbstractListModel

时间:2014-01-25 09:13:57

标签: c++ qt model-view-controller

我目前有一个QtAbstractListModel subcliass(为了清晰起见缩短了):

class HolidayTask;

class HolidayTaskModel: public QAbstractListModel
{
    Q_OBJECT
public:
    explicit HolidayTaskModel(QObject *parent = 0);
    ~HolidayTaskModel();

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

    bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
    bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());

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

private:
    QVector<HolidayTask*> m_items;

};

HolidayTask是我所包含的项目。我正在试图弄清楚需要为这个用例重新实现的内容:

  1. 模型是可修改的,但没有在视图中进行编辑:另一个小部件(不是* View子类)将进行编辑,在视图外部将显示此模型;
  2. 它不仅需要实现附加(这很容易),还需要插入和重新排序。
  3. 在追加的情况下,制作调用appendTaskbeginInsertRows的{​​{1}}函数非常容易,但至少插入和/或删除并不是一件容易的事。

    我发现的大多数代码示例都涉及就地编辑(endInsertRows等),正如我上面所写,这不是我需要的。我应该实施什么来修改此模型来完成此任务?或者,是否有任何代码示例显示这种运作方式?

2 个答案:

答案 0 :(得分:2)

如果您不需要使用视图编辑模型数据,则无需实施insertRowsremoveRowssetData。相反,您应该创建自己的修改功能,例如add_task(HolidayTask* task)set_task(int row, HolidayTask* task)remove_task(int row)。在这些函数中,您需要更改m_items值以反映数据更改。 (此外,如果您需要从列表中间插入和删除更快,则应该从QVector切换到QList。此外,您应该通知有关更改的视图:

  • 在删除行之前调用beginRemoveRows,之后调用endRemoveRows
  • 在插入行之前调用beginInsertRows,之后调用endInsertRows
  • 更改数据后致电emit dataChanged(...)

答案 1 :(得分:1)

插入就像追加,只是一行!= m_items.size():

void HolidayTaskModel::addTask(HolidayTask* task)
{
    const int row = ...find position...
    beginInsertRows(QModelIndex(), row, row);
    m_items.insert(row, task);
    endInsertRows();
}

删除任务:

void HolidayTaskModel::removeTask(HolidayTask* task)
{
    const int row = m_items.indexOf(task);
    if (row == -1)
        return;
    beginRemoveRows(QModelIndex(), row, row);
    delete m_items[row]; //only if the item is owned by the model
    m_items.remove(row);
    endRemoveRows();         
}

对于重新排序,这取决于您的确切用例,移动单个项目时使用beginMoveRows() / endMoveRows(),用于排序重新实现sort(),或者通常更容易将项目留在基础中模型未排序,让QSortFilterProxyModel代理进行排序。