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

qTableView::模型重置后和延迟后立即滚动到

  •  2
  • user1244932  · 技术社区  · 6 年前

    我使用 QTableView 和自定义模型,我想滚动到特定项目之后 模型更新。

    我创建了两个按钮“更新模型”和“滚动到”:

     btn->setText("Update model");
      QObject::connect(btn, &QPushButton::clicked, [&tbl_model, view] {
        tbl_model.update();
        auto idx = tbl_model.index(49, 0);
        qDebug() << "idx: " << idx;
        view->scrollTo(idx, QAbstractItemView::PositionAtCenter);
      });
    
      btn->setText("scroll to");
      QObject::connect(btn, &QPushButton::clicked, [view, &tbl_model] {
        auto idx = tbl_model.index(49, 0);
        qDebug() << "idx: " << idx;
        view->scrollTo(idx, QAbstractItemView::PositionAtCenter);
      });
    

    更新方法代码:

      void update() {
        beginResetModel();
        auto new_size = data_.size() == 100 ? 50 : 100;
        data_.clear();
        for (int i = 0; i < new_size; ++i) {
          data_.append(i + 1);
        }
        endResetModel();
      }
    

    如果我按“更新模型”,我的模型尺寸从50扩大到100, 然后我看到窗口底部的第49行的项目, 然后,如果我按“滚动到”按钮,我会看到它的中心。

    那我该怎么用呢 scrollTo 模型完全更新后? 我当然可以补充一下 processEvents 或使用 QTimer::singleShot ,请 但它看起来像黑客,可能有一些事件或信号 视图是否准备好滚动?

    Full code

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

    出于某种原因,视图需要在重置模型后进入事件循环(以处理某些事件),然后调用 QTableView::scrollTo()

    我觉得使用像 QTimer scrollTo this answer QueuedInvoke 功能如下:

    //the functor gets invoked in the thread where the contextObject lives
    //or in the current thread if no contextObject is provided
    template <typename Func>
    void QueuedInvoke(Func&& f, QObject* contextObject = QAbstractEventDispatcher::instance()){
        QObject signalSource;
        QObject::connect(&signalSource, &QObject::destroyed, 
                         contextObject, std::forward<Func>(f), Qt::QueuedConnection);
    }
    

    滚动到

    QueuedInvoke([view, idx]{
        view->scrollTo(idx, QAbstractItemView::PositionAtCenter);
    }, view);