更改QT AbstractListModel而无需使用现场编辑

Changing a Qt AbstractListModel without using in-place editing

本文关键字:现场 编辑 QT AbstractListModel 更改      更新时间:2023-10-16

i当前有一个qtabstractlistmodel子批量(为了清楚起见):

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. 该模型是可修改的,但是在视图中没有编辑:另一个窗口小部件(不是 *视图子类)将进行编辑,外部将显示此模型;
  2. 它不仅需要实现附加(这很容易),还需要插入和重新排序。

在附加的情况下,制作调用beginInsertRowsendInsertRowsappendTask函数非常容易,但是至少插入和/或删除并不那么微不足道。

我发现的大多数代码示例在就地编辑(createEditor等)上,如上文所写,这不是我需要的。我应该实施什么来修改此模型以完成此任务?另外,是否有任何代码示例显示此作案操作?

如果您不需要使用视图编辑模型数据,则无需实现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(...)

插入就像附加,只需行!= 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(),用于对重新进化stort()进行排序或通常更容易,或者更容易,将项目放在基本模型中,然后让qsortfilterproxymodel放在基本模型中代理进行排序。