1

I have a class that inherited from QAbstractListModel. now i want to create a signal for this class Liken below

BookListModel.h

signals:
    void currentIndexChanged(int i);

now i have want to use this in below method

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

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

but got this error:

error: C2662: 'void BookListModel::currentIndexChanged(int)': cannot convert 'this' pointer from 'const BookListModel' to 'BookListModel &'

How can i create current index changed signal for this class?

mohsen
  • 1,763
  • 3
  • 17
  • 55

2 Answers2

2

Its because the data function is const. Just declare your singal const as well and it should work:

signals:
    void currentIndexChanged(int i) const;

See this answer: Is it possible to emit a Qt signal from a const method?

Taron
  • 1,205
  • 2
  • 13
  • 29
1

I would point out that a list model should not (and it does not) know nothing about user actions, which are handled by the view.

Suppose we have a very simple model like this:

#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();
    }
};

As you can see, I added a scrolledToEnd slot, to be called when the user scrolled the view to the end. Extra items are added to the model and the layoutChanged signal is emitted to update the view. The slot is supposed to be connected to a signal which is emitted by some object who is in control of the view vertical scroll bar.

So, let's lay out a QTableView in a QMainWindow ui, and give the window a slot and a signal like these:

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

In the window constructor, we set the view model to a new instance of our Model class:

ui->setupUi(this);

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

then connect the valueChanged signal of the view's verticalScrollBar to the scrollValueChanged slot of the window:

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

and the scrolledToEnd signal of the window to the scrolledToEnd slot of the model:

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

In the window slot implementation, if the scroll bar reached its maximum value, the scrolledToEnd signal is emitted:

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

The signal will be caught by the model slot, and a new set of ten items will be appended to the model.

p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35