【问题标题】:QT: changing the tab traversal order on runtime?QT:在运行时更改选项卡遍历顺序?
【发布时间】:2013-01-21 13:46:20
【问题描述】:

你可能会说我对 QT 很陌生...

我的程序在 QGridLayout 中包含一个带有多个小部件的窗口。其中一些小部件本身具有布局和子小部件。按 T​​ab 键会按照我创建小部件的顺序移动焦点。

当小部件更改其内容时会出现问题(我通过删除所有子小部件然后构建新小部件来做到这一点。)如果我这样做,新小部件将移动到选项卡链的末尾(这表明我,选项卡顺序是一种全局的窗口)。我尝试使用 QWidget::setTabOrder() 重新排序所有小部件(我尝试了两种方法,只为主窗口的竞争设置标签顺序并为子窗口设置它)但实际顺序没有改变。我通过在小部件的竞争发生变化时发出信号并将其连接到我的主窗口上的插槽来做到这一点。 我想我理解 setTabOrder() 函数的工作方式。我做了类似的事情:

QWidget* a = firstWidget;
QWidget* b = secondWidget;
QWidget::setTabOrder(a,b);
for (int i = 0; i < widgets.size(); ++i) {
  a = b;
  b = widgets[i];
  QWidget::setTabOrder(a,b);
}

在更改 Tab 键顺序时有什么特别需要做的吗?

我还尝试重新实现 focusNextPrevChild(bool next) 和 focusInEvent(QFocusEvent* e) 类似于可以在此站点上找到的内容。 1

我设法弄乱了标签顺序,更像这样......这种方法是朝着正确方向迈出的一步吗?

如果这是我设法错过的简单事情,我很抱歉,但我现在苦苦挣扎了一段时间,找不到解决方案。 非常感谢任何帮助。

【问题讨论】:

  • 我不确定这是否能解决问题,但如果firstWidgetwidgets[0] 相同,您的循环应该从 1 开始
  • widgets 是如何填充的,它包含哪些小部件?只有更改其内容的小部件的子级,还是主布局的所有小部件?
  • 您有一些已删除的小部件,还有一些新的小部件。例如,您有 1、2、3、4、5 个小部件,但接下来您有 1、2、5 个小部件,而 6、7 是新的小部件。如果将 Tab 键顺序设置为 1、2、6、7、5 会怎样?
  • @TimMeyer 我都试过了,还从布局中拉出小部件。 (我使用了 QGridLayout::itemAtPosition(),然后使用了 QLayoutItem::Widget(),对孩子也是如此。)
  • @Milovidov 这就是我尝试做的,但我无法让它发挥作用。

标签: qt user-interface tab-ordering


【解决方案1】:

我遇到了同样的问题,并使用 cmets 中提供的 Tim Meyer 信息解决了它。

Tab 顺序不是分层的 - 在不接受焦点的父窗口小部件上调用 setTabOrder 不会导致焦点传递给子窗口。您将需要从小部件中获取适当的子级并设置它们的顺序

在我的例子中,动态构造的 QTreeWidget 包含可编辑的小部件,我需要重置 setTabOrder 以解决无序创建的小部件。

以下代码是(大部分)实现

// Perform a depth-first gather of the child widgets of this item
void gatherTabWidgets( QObject* item, QWidgetList& tabWidgets )
{
  if (item->isWidgetType())
  {
    QWidget* itemWidget = static_cast<QWidget*>(item);
    if (itemWidget->focusPolicy() & Qt::TabFocus)
      tabWidgets.push_back( itemWidget );
  }
  const QObjectList& children = item->children();
  for (QObjectList::const_iterator itr = children.begin(); itr != children.end(); itr++)
  {
    gatherTabWidgets( const_cast<QObject*>(*itr), tabWidgets );
  }
}

// Perform a depth-first gather of the child items widgets;
void gatherTabWidgets( QTreeWidgetItem* item, QWidgetList& tabWidgets )
{
  QWidget* itemWidget = fetchWidgetForItem( item );
  gatherTabWidgets( itemWidget, tabWidgets );

  for (int i = 0; i < item->childCount(); i++)
  {
    gatherTabWidgets( item->child( i ), tabWidgets );
  }
}

void VETreeWidget::sortTree()
{
  // Ensure ordering is maintained.
  sortItems( 0, Qt::AscendingOrder );

  // Once the items have been re-ordered, re-create the tab ordering
  QTreeWidgetItem* baseItem = topLevelItem( 0 );
  QWidgetList tabWidgets;
  gatherTabWidgets( baseItem, tabWidgets );

  if (!tabWidgets.empty())
  {
    QWidget* lastWidget = tabWidgets.first();
    // Connect this treeview to the first widget.  This ensures
    // if the treeview is tabbed-to, it will tab to the correct sub-widget
    setTabOrder( this, lastWidget );
    for (QWidgetList::iterator itr = tabWidgets.begin() + 1; itr != tabWidgets.end(); itr++)
    {
      setTabOrder( lastWidget, *itr );
      lastWidget = *itr;
    }
  }
}

【讨论】:

    猜你喜欢
    • 2017-12-17
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多