QT:在运行时改变标签遍历顺序



你可能会觉得我对QT很陌生…

我的程序在QGridLayout中包含一个带有几个小部件的窗口。其中一些小部件本身有布局和子小部件。按Tab键移动焦点,就像我所期望的那样,按照我创建小部件的顺序。

当一个小部件改变它的内容时就会出现问题(我通过删除所有的子小部件然后构建新的小部件来做到这一点)。如果我这样做,新的小部件将被移动到选项卡链的末尾(这对我来说,选项卡顺序对窗口来说是全局的)。我尝试使用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

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

我很抱歉,如果这是一些简单的东西,我设法错过了,但我现在挣扎了一段时间,我找不到一个解决方案。

我有同样的问题,并使用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;
    }
  }
}

最新更新