Как реагировать на внутренние перемещения в QT listview QStringListModel - PullRequest
0 голосов
/ 09 марта 2020

Мое приложение почти готово. Я застрял, пытаясь обновить элементы моего главного окна, когда я перемещаю элемент вверх или вниз в простой модели списка, в качестве основы которой используется QStringListModel.

Вот моя модель для разрешения перетаскивания:

#ifndef MYMODEL_H
#define MYMODEL_H

#include <QStringListModel>

class mymodel : public QStringListModel
{
public:
    mymodel(QObject * parent = nullptr);
    Qt::ItemFlags flags(const QModelIndex &index) const;
};
#endif // MYMODEL_H

Реализация модели:

#include "mymodel.h"

mymodel::mymodel(QObject *parent) : QStringListModel (parent) {}

Qt::ItemFlags mymodel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags defaultFlags = QStringListModel::flags(index);

    if (index.isValid())
    {
        return  Qt::ItemIsSelectable | Qt::ItemIsDragEnabled |
                Qt::ItemIsEnabled ;
    }
    else
    {
        return  Qt::ItemIsSelectable  | Qt::ItemIsDragEnabled |
                Qt::ItemIsDropEnabled | defaultFlags;
    }
}

Вот моя реализация, которая работает, за исключением того, что я не могу определить, перемещаю ли я строку вверх вниз.

    //create model
    model = new mymodel(this);

    //make some data
    QStringList List;
    List << "one" << "two" << "three";

   // populate the model
    model->setStringList(List);

    // create a list view
     QListView *lv = new QListView(this);

    // glue model and view together
    lv->setModel(model);

    // allow modifying the data in Listview
    lv->setDragDropMode(QAbstractItemView::InternalMove);
    lv->setDragDropOverwriteMode(false);
    lv->setEditTriggers(QAbstractItemView::AnyKeyPressed |
                        QAbstractItemView::DoubleClicked);

Я пробовал все следующее, они компилируются, но ничего не делают.

Они должны просто печатать консоль 'что-то случилось', но они этого не делают.

    // doesnt do anything! compiles
    connect(lv, &QListView::indexesMoved,
            this, &MainWindow::rowsMoved);

    // doesnt do anything! compiles
    connect(lv->model(), &QStringListModel::rowsMoved,
            this, &MainWindow::rowsMoved);

    // doesnt do anything! compiles
    connect(lv->model(), &QAbstractItemModel::rowsMoved,
            this, &MainWindow::rowsMoved);

rowMoved объявляется в заголовках с помощью:

void rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row);
};

Тем временем я обнаружил, что добавление к конструктору:

lv->installEventFilter(this);

В cpp также как позже определено как:

bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if (object == lv)
    {
        if (event->type() == QEvent::ChildRemoved) {
            qDebug() << "drop event!";

        // iterate over the listview and print out it's data,
        // so if you wanted this back in your stringlist.. this is
        // where you'd do it:
        for (int i = 0; i < model->rowCount(); ++i)
        {
            qDebug().noquote() <<  model->index(i, 0).data(Qt::DisplayRole).toString();
        }
        return true;
        }
    }
    return false;
}

Это дает мне «уведомление о бедняке», но кажется «грязным»

1 Ответ

0 голосов
/ 10 марта 2020

Так благодарен, что eyllanes c помог мне! Спасибо.

Публикуйте это здесь, если это понадобится.

Этот код действительно позволяет мне редактировать элементы, перемещать их вверх / вниз в виде списка и получать уведомления, когда что-то в список изменяется пользователем. Кроме того, ниже не показано, что ниже разрешены операции перетаскивания из файлового менеджера, которые для моего приложения мне нужны.

Если вы сравните мой оригинальный пост на основе QStringListModel, вы заметите, что они выглядят почти точно одни и те же. Я все еще озадачен, почему использование этой модели не сработало. Но факты есть факты, это работает, а другой нет.

mymodel.h

#ifndef MYMODEL_H
#define MYMODEL_H

#include <QStandardItemModel>
class mymodel : public QStandardItemModel
{

public:
    mymodel(QObject * parent = nullptr);
    Qt::ItemFlags flags(const QModelIndex &index) const;
};

#endif // MYMODEL_H

mymodel. cpp

#include "mymodel.h"
#include <QDebug>

mymodel::mymodel(QObject *parent) : QStandardItemModel (parent) {}

Qt::ItemFlags mymodel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);

    if (index.isValid())
    {
        return  Qt::ItemIsSelectable | Qt::ItemIsDragEnabled |
                Qt::ItemIsEnabled    | Qt::ItemIsEditable;
    }
    else
    {
        return  Qt::ItemIsSelectable  | Qt::ItemIsDragEnabled |
                Qt::ItemIsDropEnabled | defaultFlags;
    }
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QListView>
#include <QStandardItemModel>
#include <QStringList>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QListView *lv;
    QStringList list;
    QStandardItemModel *model;

private slots:
    void itemChanged();
};
#endif // MAINWINDOW_H

главное окно. cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBoxLayout>
#include <QDebug>
#include "mymodel.h"

MainWindow::MainWindow(QWidget *parent)
{
    lv = new QListView(this);
    model = new mymodel(lv);

    list << "one" << "two" << "three";
    for (int i=0; i < list.length(); ++i)
    {
        model->appendRow(new QStandardItem(list[i]));
    }

    lv->setModel(model);
    lv->setDragDropMode(QAbstractItemView::InternalMove);
    lv->setDragDropOverwriteMode(false);
    QBoxLayout *lo = new QBoxLayout(QBoxLayout::LeftToRight);
    lo->addWidget(lv);
    setLayout(lo);

    connect(model, &QStandardItemModel::itemChanged,
            this,  &MainWindow::itemChanged);
}

MainWindow::~MainWindow()
{
}

void MainWindow::itemChanged()
{
    qDebug().noquote() << "an item changed";
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QListView>
#include <QStandardItemModel>
#include <QStringList>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QListView *lv;
    QStringList list;
    QStandardItemModel *model;

private slots:
    void itemChanged();
};
#endif // MAINWINDOW_H
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...