1

我有一个继承自 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 &”

如何为此类创建当前索引更改信号?

4

2 回答 2

2

是因为data功能是const。只需声明您的信号 const 并且它应该可以工作:

signals:
    void currentIndexChanged(int i) const;

看到这个答案:Is it possible to emit a Qt signal from a const method?

于 2018-04-17T13:52:28.913 回答
1

我要指出,列表模型不应该(而且它也不)对视图处理的用户操作一无所知。

假设我们有一个非常简单的模型,如下所示:

#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所以,让我们在ui 中布局 a 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();
    }
}

该信号将被模型槽捕获,并且一组新的十个项目将附加到模型中。

于 2018-04-17T15:26:00.363 回答