Как создать сигнал CurrentIndexChanged для QAbstractListModel в qt?

У меня есть класс, унаследованный от QAbstractListModel. теперь я хочу создать сигнал для этого класса.

BookListModel.h

signals:
    void currentIndexChanged(int i);

теперь я хочу использовать это в методе ниже

QVariant BookListModel::data(const QModelIndex &index, int role) const{

    int i=index.row();
    emit currentIndexChanged();
}

но получил эту ошибку:

ошибка: C2662: «void BookListModel:: currentIndexChanged (int)»: невозможно преобразовать указатель «this» из «const BookListModel» в «BookListModel &»

Как я могу создать текущий сигнал изменения индекса для этого класса?


person mohsen    schedule 17.04.2018    source источник
comment
использовать сигнал dataChanged   -  person Simon    schedule 17.04.2018
comment
Что вы подразумеваете под текущий индекс?   -  person p-a-o-l-o    schedule 17.04.2018
comment
@p-a-o-l-o Я хочу использовать это для загрузки напоминания о списке. Я использовал эту модель списка в GridView, и когда пользователь прокрутил до конца, я хочу загрузить, например, еще 10 книг в конце книги   -  person mohsen    schedule 17.04.2018
comment
@mohsen, вы должны учитывать, что модель ничего не знает о выборе пользователя, прокрутке и т. Д. Это должно быть представление для отслеживания таких действий.   -  person p-a-o-l-o    schedule 17.04.2018
comment
Также: под GridView вы подразумеваете QTableView или что-то еще?   -  person p-a-o-l-o    schedule 17.04.2018


Ответы (2)


Это потому, что функция data является const. Просто объявите свой singal const, и он должен работать:

signals:
    void currentIndexChanged(int i) const;

См. этот ответ: Можно ли сгенерировать сигнал Qt из константного метода?

person Taron    schedule 17.04.2018

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

Предположим, у нас есть очень простая модель:

#include <QAbstractListModel>

class Model : public QAbstractListModel
{
    Q_OBJECT
    QStringList list;

public:
    Model()
    {
        //adds 100 items
        for(int i=0; i<100; i++)
            list << QString("ITEM #") + QString::number(i+1);
    }

    int rowCount(const QModelIndex &parent) const
    {
        return list.size();
    }
    QVariant data(const QModelIndex &index, int role) const
    {
        if(index.isValid() && (role == Qt::DisplayRole))
        {
            int row = index.row();
            if(row < list.size())
            {
                return list[row];
            }
        }
        return QVariant();
    }

public slots:
    void scrolledToEnd()
    {
        //adds 10 more items
        int count = list.size();
        for(int i=count; i<(count + 10); i++)
            list << QString("ITEM #") + QString::number(i+1);

        emit layoutChanged();
    }
};

Как видите, я добавил слот scrolledToEnd, который будет вызываться, когда пользователь прокручивает представление до конца. В модель добавляются дополнительные элементы, и выдается сигнал layoutChanged для обновления представления. Предполагается, что слот связан с сигналом, который излучается каким-либо объектом, который контролирует вертикальную полосу прокрутки представления.

Итак, давайте разместим QTableView в QMainWindow пользовательском интерфейсе и дадим окну слот и сигнал вроде этих:

public slots:
    void scrollValueChanged(int value);
signals:
    void scrolledToEnd();

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

ui->setupUi(this);

Model * model = new Model();
ui->tableView->setModel(model);

затем подключите сигнал valueChanged verticalScrollBar представления к слоту scrollValueChanged окна:

connect(ui->tableView->verticalScrollBar(), &QScrollBar::valueChanged, this, &MainWindow::scrollValueChanged);

и сигнал scrolledToEnd окна в слот scrolledToEnd модели:

connect(this, &MainWindow::scrolledToEnd, model, &Model::scrolledToEnd);

В реализации оконного слота, если полоса прокрутки достигает своего максимального значения, выдается сигнал scrolledToEnd:

void MainWindow::scrollValueChanged(int value)
{
    if(value==ui->tableView->verticalScrollBar()->maximum())
    {
        emit scrolledToEnd();
    }
}

Сигнал будет пойман слотом модели, и к модели будет добавлен новый набор из десяти предметов.

person p-a-o-l-o    schedule 17.04.2018