QListView moveRow () из модели не вызывается - PullRequest
0 голосов
/ 02 декабря 2019

У меня 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.cpp ListModel.h

Другой подход заключается в создании userRole для самого изображения. Здесь я попытался переопределить roleNames () как

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

и проверить роли в setdata () / data (), но это тоже не сработало.

Каков наилучший способиметь сложную модель и перемещать их в виде списка?

1 Ответ

0 голосов
/ 02 декабря 2019

Поскольку уже кратко ответил в списке интересов Qt:

Поскольку moveRows был добавлен в Qt 5.x, а перетаскивание в Qt 4 и до сих пор используетinsert + remove для обратной совместимости.

Я бы добавил, что "moveRows", я полагаю, считается "оптимизацией" и не является обязательным требованием для модели, и представление не может знать,методы перемещения действительно реализованы. Поскольку для редактируемой модели требуются функции удаления / вставки, вызывать их по умолчанию «безопаснее».

Вы можете повторно реализовать метод dropMimeData() модели и самостоятельно вызывать moveRows(). Но предостережение заключается в том, что вы должны вернуть false из метода, если вы сделаете это. Если вы вернете true к Qt::MoveAction, представление все равно будет пытаться удалить строку из старой позиции в модели (что, очевидно, не то, что вы хотите).

...