【问题标题】:How to detect QTableWidget scroll source (code itself/user (wheel)/user (scrollbar))?如何检测QTableWidget滚动源(代码本身/用户(滚轮)/用户(滚动条))?
【发布时间】:2012-08-22 19:47:57
【问题描述】:

我正在使用 Qt 4.8 编写一个程序,该程序显示一个包含文件名和文件参数的表 (QTableWidget)。首先,用户将文件添加到列表中,然后单击进程。代码本身使用简单的进度描述更新表的内容。我希望默认情况下自动滚动表格以显示最后处理的文件并且该代码已准备好。

如果我想手动滚动它,一旦发生变化,小部件就会自动滚动,将视口移动到最后一个元素。如果我检测到是用户想要更改视图,我希望能够覆盖自动滚动。

在许多终端仿真器程序中都可以看到这种行为。当添加新行时,视图会滚动,但当用户强制终端查看之前的一些行时,终端不会尝试向下滚动。

我该怎么做?

解决方案:

我创建了一个对象,它过滤由我的 QTableWidget 和 QScrollBar 处理的事件。如果我发现应该关闭自动滚动的事件,我只需设置一个标志并在设置该标志时停止滚动视图。

一切都在 tableController 类中实现。以下是三个关键方法的部分内容。

bool tableController::eventFilter(QObject* object, QEvent* event)
{
  switch (event->type())
  {
    case QEvent::KeyPress:
    case QEvent::KeyRelease:
    case QEvent::Wheel:
    case QEvent::MouseButtonDblClick:
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
      _autoScrollEnabled = false;
    default:
      break;
  }
  return QObject::eventFilter(object, event);
}

void tableController::changeFile(int idx)
{
  [...]
  if (_autoScrollEnabled)
  {
    QTableWidgetItem* s = _table.item(_engine.getLastProcessed(), 1);
    _table.scrollToItem(s);
  }
  [...]
}

void tableController::tableController()
{
   [...]
   _autoScrollEnabled = true;
   _table.installEventFilter(this);
   _table.verticalTableScrollbar()->installEventFilter(this);
   [...]
}

感谢所有帮助。我希望有人会觉得它有用:)

【问题讨论】:

    标签: qt qtablewidget


    【解决方案1】:

    子类QTableWidget 并重载它的wheelEvent。您可以使用提供的QWheelEvent 对象的参数来确定用户是向上还是向下滚动。

    然后使用在wheelEvent 覆盖中设置(或重置)的简单布尔标志。负责调用scrollToBottom() 的方法应该考虑这个布尔标志。

    您必须找到一种方法来确定何时设置或重置该标志,例如当用户向上滚动时总是设置它,当用户向下滚动并且当前显示的区域在底部时重置它。

    【讨论】:

    • 问题不仅在于滚轮滚动,还在于用户推动箭头、向上/向下翻页以及使用提供的垂直滚动条(同样,通过滚轮滚动或使用末端的按钮)。滚动视图的方式有很多种,我想在某个地方点按一下,我可以一次完成所有操作。
    • 你可以使用QObject::installEventFilter(),然后使用switch/case而不是QEvent::type()来一次处理多个事件。
    • 好的,这更有意义。我会试试这个。我想我将不得不找出发送了哪些事件以及发送它们的人。
    • 如果你在 QTableWidget 上安装了事件过滤器,那应该就够了.. 你正在寻找专门针对 WheelEvent、ScrollEvent 和 KeyPressEvent
    • 我不知道是只有 QTableWidget 获取所有事件还是滚动条也获取这些消息。我可能需要在这两个地方点击...
    【解决方案2】:
    connect(_table->view()->verticalScrollBar(), &QAbstractSlider::actionTriggered, this, [this](int) {
        _autoScrollEnabled = false;
    });
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2010-10-11
    • 2021-07-08
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    相关资源
    最近更新 更多