QListView moveRow()来自模型未调用

问题描述 投票:0回答:1

我有一个Listview,它应该显示图像的预览。为此,我创建了一个项目“ ListItem”

class ListItem
{
public:
    ListItem();
    ListItem(QString name, QImage image);
    QImage* previewIcon();
    void setPreviewIcon(QImage icon);
    QImage *image();
    void setImage(QImage* image);
    void setImage(QImage image);
    void setName(QString name);
    void setChecked(bool checked);
    QString name();
    bool checked();
private:
    QImage m_preview;
    QImage m_image;
    QString m_name;
    bool m_checked;
};

此模型存储其自身的图像及其预览。这适用于插入和删除项目:

class ListModel: public QAbstractListModel
{
    Q_OBJECT

public:
        ListModel(QObject *parent = nullptr);
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
        Qt::ItemFlags flags(const QModelIndex &index) const override;
        QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
        bool removeRow(int row, const QModelIndex &parent = QModelIndex());
        bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
        bool insertRow(int row, const QModelIndex &parent = QModelIndex());
        bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
        bool appendItem(ListItem* item);
        bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
        bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
        Qt::DropActions supportedDropActions() const override;
        QHash<int, QByteArray> roleNames() const override;
private:
        ListItem* getItem(const QModelIndex &index) const;
 private:
    QList<ListItem*> m_scannedDocuments;
};

这是QListView的设置:

m_scannedDocumentsModel = new ListModel();
m_scannedDocuments = new QListView();
m_scannedDocuments->setModel(m_scannedDocumentsModel);
m_scannedDocuments->setDragDropMode(QAbstractItemView::InternalMove);
m_scannedDocuments->setMovement(QListView::Snap);
m_scannedDocuments->setDefaultDropAction(Qt::MoveAction);

拖放操作适用于预览,名称以及是否已选中。问题是图像“ m_image”。当我在视图中移动时,该视图调用insertRows()并插入一个新项目并删除旧项目,但不调用moveRows。

为什么不调用moveRows()?

在这里您可以找到完整的实现:ListModel.cppListModel.h

另一种方法是为其自身的图像创建一个userRole。在这里,我尝试重新实现roleNames()为

QHash<int, QByteArray> ListModel::roleNames() const {
    QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
    roles[Qt::UserRole] = "Qt::UserRole";
    return roles;
}

并检查setdata()/ data()中的角色,但这也不起作用。

拥有复杂模型并将其移至列表视图的最佳方法是什么?

qt qabstractitemmodel qlistview
1个回答
0
投票

作为Qt兴趣清单上的already answered的简要介绍:

因为在Qt 5.x中添加了moveRows,并在Qt 4中添加了拖放功能,但仍使用insert + remove来实现向后兼容性。

我要补充一点,我认为“ moveRows”被认为是“优化”,并不是对模型的真正要求,并且视图无法知道move方法是否真正实现。由于可编辑模型需要删除/插入功能,因此默认情况下调用它们是“安全的”。

您可以重新实现模型的dropMimeData()方法并自己调用moveRows()。但是,需要注意的是,如果执行此操作,则应从方法中返回false。如果将true返回到Qt::MoveAction,则视图仍将尝试从模型的旧位置删除行(显然这不是您想要的行)。

© www.soinside.com 2019 - 2024. All rights reserved.