0

私が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

私はこのようにタブオーダーをもっと台無しにすることができました...このアプローチは正しい方向への一歩ですか?

これが私が見逃した単純なものである場合は申し訳ありませんが、しばらく苦労しており、解決策が見つかりません. どんな助けでも大歓迎です。

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 に答える