代码之家  ›  专栏  ›  技术社区  ›  mohsen

如何在qt中为QAbstractListModel创建CurrentIndexChanged信号?

  •  1
  • mohsen  · 技术社区  · 6 年前

    我有一个从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&”

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

    2 回复  |  直到 6 年前
        1
  •  2
  •   Taron    6 年前

    这是因为 data 函数为 const 。 只需声明您的singal const,它就会起作用:

    signals:
        void currentIndexChanged(int i) const;
    

    请参见以下答案: Is it possible to emit a Qt signal from a const method?

        2
  •  1
  •   p-a-o-l-o    6 年前

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

    假设我们有这样一个非常简单的模型:

    #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 slot,当用户将视图滚动到末尾时调用。将向模型和 layoutChanged 发出信号以更新视图。插槽应该连接到由控制视图垂直滚动条的某个对象发出的信号。

    那么,让我们布置一个 QTableView 在a中 QMainWindow ui,并为窗口提供如下插槽和信号:

    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);
    

    以及 滚动结束 车窗信号至 滚动结束 型号插槽:

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

    在窗口插槽实现中,如果滚动条达到其最大值 滚动结束 发出信号:

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

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