0

您可能会说我对 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);
}

更改标签顺序时有什么特别的事情要做吗?

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

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

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

4

1 回答 1

1

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

选项卡顺序不是分层的 - 在不接受焦点的父小部件上调用 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;
    }
  }
}
于 2016-01-25T02:48:39.873 回答