首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何自动保持一个QTextEdit,QAbstractItemView,QAbstractScrollArea等滚动到底部?

如何自动保持一个QTextEdit,QAbstractItemView,QAbstractScrollArea等滚动到底部?
EN

Stack Overflow用户
提问于 2018-08-29 21:49:54
回答 1查看 148关注 0票数 2

一种常见的行为是,如果用户没有在其他地方滚动,则将"log“输出小部件滚动到底部。有一些特定于窗口小部件的解决方案,即特定于QTextEditQListView等,但它们总是需要更改用户代码-而且用户代码已经做了正确的事情,并将数据附加到视图使用的模型中。更改该代码会不适当地将其与视图的细节绑定在一起,因此会有一种糟糕的软件设计味道。

因此,人们可能希望的是一种在不更改用户代码的情况下修改小部件本身行为的方法。此外,也许有一种方法可以在几乎所有从QAbstractScrollArea派生的类中工作

EN

回答 1

Stack Overflow用户

发布于 2018-08-29 21:49:54

一个可行的解决方案只需要访问视图的滚动条,并且可以很容易地适应于使用滚动条的任何小部件-不仅仅是QAbstractScrollArea,即使Qt提供的所有垂直滚动小部件确实派生自这个小部件(它们应该是这样的!)。

允许这种低级方法的关键观察结果是,无论何时将内容追加到小部件,垂直滚动条的范围都会发生变化。因此:

每当scrollbar的range改变时,我们滚动到底部当我们在state.

  • Whenever scrollbar的value改变的viewAtBottom中时,我们更新viewAtBottom以反映scrollbar是否在其范围的末尾(最大值)。

这允许用户在内容中自由滚动而不受干扰,但当滚动条放置在那里时,滚动条将“粘在”范围的末尾。

当然,人们希望有一种方法可以为QScrollBar注入这种行为,但没有任何标志可以启用它-至少在Qt 5.11版本中是这样。

QAbstractScrollArea (即QListViewQListWidgetQTextEditQTextBrowserQPlainTextEdit等任何项目视图)上调用以下函数时,将使其在添加内容和滚动条范围扩大时保持在底部的行为。

下面的代码在Qt5中工作,并且可以简单地修改为Qt4,将lambdas重新实现为助手类中的插槽。直接获取滚动条的函数也可以被分解出来。

代码语言:javascript
运行
复制
// https://github.com/KubaO/stackoverflown/tree/master/questions/qdebug-window-output-52061269
[...]
void rescrollToBottom(QAbstractScrollArea *view) {
   static const char kViewAtBottom[] = "viewAtBottom";
   auto *scrollBar = view->verticalScrollBar();
   Q_ASSERT(scrollBar);
   auto rescroller = [scrollBar]() mutable {
      if (scrollBar->property(kViewAtBottom).isNull())
         scrollBar->setProperty(kViewAtBottom, true);
      auto const atBottom = scrollBar->property(kViewAtBottom).toBool();
      if (atBottom) scrollBar->setValue(scrollBar->maximum());
   };
   QObject::connect(scrollBar, &QAbstractSlider::rangeChanged, view, rescroller,
                    Qt::QueuedConnection);
   QObject::connect(scrollBar, &QAbstractSlider::valueChanged, view, [scrollBar] {
      auto const atBottom = scrollBar->value() == scrollBar->maximum();
      scrollBar->setProperty(kViewAtBottom, atBottom);
   });
}

有关此代码实际运行的完整示例,请参阅this answer

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52079035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档