Qt Quickのフォーカス管理徹底解説:nextItemInFocusChain()の活用法

2025-06-06

Item.nextItemInFocusChain()は、Qt Quick(QML)のItem型に属するメソッドで、特にキーボード操作によるフォーカス移動を制御する際に重要な役割を果たします。

簡単に言うと、現在のアイテムから見て、タブキー(またはShift+タブキー)を押したときに次にフォーカスが移動するアイテムを返します。

なぜこれが重要なのか?

GUIアプリケーションにおいて、ユーザーはしばしばキーボードを使ってUI要素間を移動します。特に、入力フィールドを次々と移動したり、ボタンをTabキーで選択したりする際にこの機能が使われます。Item.nextItemInFocusChain()は、この「フォーカスチェーン(Focus Chain)」と呼ばれるフォーカルな移動順序をプログラマが把握し、場合によっては制御するために提供されています。

動作のメカニズム

Qt Quickでは、フォーカスチェーンはデフォルトでQMLツリーの視覚的な順序に基づいて自動的に構築されます。つまり、通常はQMLファイル内で定義された順序(上から下、左から右)でフォーカスが移動します。

しかし、複雑なUIや特定のユーザーエクスペリエンスを考慮する場合、このデフォルトの順序では不十分なことがあります。そのような場合に、Item.focusプロパティやItem.Keys.onTabPressedなどのイベントハンドラと組み合わせて、明示的にフォーカスの移動先を制御することが可能です。

Item.nextItemInFocusChain()は、以下の情報を考慮して次のアイテムを特定します。

  1. Item.nextItemInFocus プロパティ
    もし現在のアイテムでnextItemInFocusプロパティが明示的に設定されていれば、そのアイテムが次のフォーカス先となります。
  2. Item.Keys.tab プロパティ
    通常は自動ですが、Keys.tabプロパティが利用可能なアイテムを検出します。
  3. 視覚的な順序
    nextItemInFocusが設定されていない場合、QMLツリーにおける視覚的な順序に基づいて次に適切なアイテムが選択されます。

通常、このメソッドを直接呼び出すことは稀です。多くの場合、Qt Quickの自動的なフォーカス管理に任せます。しかし、デバッグや特定の複雑なフォーカスロジックを実装する際に、現在のアイテムの次のフォーカス先がどこになるのかを確認するために使用することができます。

例えば、カスタムのキーボードナビゲーションを実装する際に、特定の条件で通常のフォーカスチェーンをスキップして別のアイテムにフォーカスを移動させたい場合、Item.nextItemInFocusChain()を使って次のデフォルトのアイテムを取得し、それとは異なるアイテムにフォーカスをセットする、といった応用が考えられます。

// これは概念的なコードであり、通常は直接使うことは少ないです
Item {
    id: myItem
    focus: true // 例としてフォーカスがある状態

    Keys.onTabPressed: {
        var nextDefaultItem = myItem.nextItemInFocusChain(true); // 引数trueで順方向のフォーカスを問い合わせ
        console.log("次のデフォルトのフォーカスアイテム:", nextDefaultItem);

        // ここで、もしnextDefaultItemが特定の条件を満たさなければ、
        // 別のアイテムにフォーカスを移動させるロジックを実装することも可能
        // if (nextDefaultItem === someOtherItem) {
        //     anotherItem.focus = true;
        //     event.accepted = true; // デフォルトのタブ動作を抑制
        // }
    }
}


Item.nextItemInFocusChain()は、Qt Quickのフォーカス管理の内部的な動作を理解するために役立つメソッドですが、このメソッド自体を直接呼び出して問題が発生することは稀です。 むしろ、フォーカスチェーン全体の動作が意図通りにならない場合に、その原因究明のためにこのメソッドの振る舞いを考えることになります。

したがって、ここで説明する「エラーとトラブルシューティング」は、Item.nextItemInFocusChain()の呼び出しエラーというよりは、Qt Quickのフォーカス管理が期待通りに機能しない場合の一般的な問題とその解決策に焦点を当てます。

フォーカスが意図しないアイテムに移動する

原因

  • キーイベントのハンドリング不足/過剰
    Keys.onTabPressedなどのイベントハンドラでevent.accepted = trueを適切に設定していない(または設定しすぎている)ため、デフォルトのフォーカス移動が抑制されたり、二重に処理されたりする。
  • Disabled/Invisibleなアイテム
    enabled: falsevisible: falseのアイテムはフォーカスチェーンに含まれません。
  • QMLツリーの視覚的な順序の誤解
    QMLファイル内でのアイテムの定義順序が、ユーザーが期待するタブ移動の順序と異なっている。特に、複雑なレイアウト(Row, Column, Grid, StackLayoutなど)を使用している場合、子アイテムの順序が直感と異なることがあります。
  • Item.nextItemInFocus の誤設定
    特定のアイテムのnextItemInFocusプロパティが誤ったアイテムを指している。
  • Item.focus プロパティの設定漏れ
    フォーカスを受け取るべきアイテムにfocus: trueが設定されていない。

トラブルシューティング

  • キーイベントハンドラの調整
    Keys.onTabPressedなどをカスタマイズしている場合、event.accepted = trueが適切なタイミングで呼び出されているかを確認します。これにより、QMLのデフォルトのフォーカス処理が抑制されます。
  • enabledとvisibleの確認
    フォーカスが当たらないアイテムが、意図せず無効化または非表示になっていないかを確認します。
  • QMLツリーとフォーカス順序の可視化
    デバッガやconsole.logを使って、Item.nextItemInFocusChain(true)Item.nextItemInFocusChain(false)(順方向/逆方向)の返り値を表示し、実際のフォーカス移動順序を把握します。
  • nextItemInFocusのレビュー
    もしnextItemInFocusを使用している場合は、その設定が意図通りのアイテムを指しているか、また、それが循環参照になっていないかを確認します。
  • focus: trueの確認
    フォーカスを受け取るすべての対話型アイテム(TextInput, Buttonなど)にfocus: trueが設定されているか確認します。

フォーカスが全く移動しない、または特定のアイテムで止まる

原因

  • キーイベントの横取り
    画面全体や親要素でKeys.onTabPressedevent.accepted = trueで処理されており、子要素にイベントが伝播していない。
  • フォーカスチェーンの断裂
    何らかの理由でフォーカスチェーンが途中で途切れている(例: 特定のアイテムがフォーカスを渡す設定になっていない)。
  • フォーカス可能なアイテムが他にない
    現在フォーカスを持っているアイテム以外に、focus: trueが設定されたアイテムが存在しない。

トラブルシューティング

  • デバッグ出力
    Item.nextItemInFocusChain()の呼び出し結果をconsole.logで出力し、次のアイテムがnullであるか、期待するアイテムであるかを確認します。
  • イベントフィルタリングの調査
    EventFilterなどを用いてキーイベントを処理している場合、それがタブキーイベントを横取りしていないか確認します。
  • nextItemInFocusの循環参照/未設定
    nextItemInFocusを明示的に設定している場合、それが有効なアイテムを指しているか、または無限ループになっていないかを確認します。
  • フォーカス可能アイテムの確認
    UI上のすべての対話型アイテムがfocus: trueになっているかを確認します。

Item.nextItemInFocusChain()がnullを返す

原因

  • フォーカスチェーンの終端
    現在のアイテムがフォーカスチェーンの最後に位置している。
  • 現在のアイテムから見て、有効な次のフォーカス可能アイテムが存在しない。

トラブルシューティング

  • デバッグ中であれば、本当に次のアイテムが存在しないのか、それとも見落としているフォーカス可能アイテムがあるのかを確認します。
  • アプリケーションのロジックとして、フォーカスチェーンが一周するようにしたいのであれば、最後のアイテムのnextItemInFocusを最初のアイテムに設定するなどの対応が必要です。
  • これはエラーというよりは、フォーカスチェーンの末端に到達したことを示す正常な動作である場合が多いです。

原因

  • QMLツリーの視覚的な順序の誤解
    順方向と同様に、QMLツリーの逆順が期待と異なる。
  • nextItemInFocusは順方向のみに作用
    nextItemInFocusプロパティは、基本的にタブキー(順方向)での移動に影響を与えます。Shift+タブキー(逆方向)の移動には、特別な設定がない限り、QMLツリーの逆順が適用されます。

トラブルシューティング

  • console.logを使って、Item.nextItemInFocusChain(false)が実際に返すアイテムを確認し、QMLツリーの構造と照らし合わせます。
  • nextItemInFocusは主に順方向の制御に使用されることを理解します。逆方向のフォーカスを厳密に制御したい場合は、Keys.onShiftTabPressedイベントハンドラで、明示的に前のアイテムにフォーカスをセットするロジックを実装する必要があります。

Item.nextItemInFocusChain()自体がエラーを出すことは稀で、これはあくまでフォーカスチェーンの次のアイテムを問い合わせるためのメソッドです。問題が発生する場合、それは通常、Qt Quickのフォーカス管理のルール(focusプロパティ、nextItemInFocus、QMLツリーの順序、キーイベントハンドリング)が意図通りに適用されていないことに起因します。

トラブルシューティングの際は、以下の点を順に確認していくと良いでしょう。

  1. 各アイテムのfocusプロパティは正しく設定されているか?
  2. nextItemInFocusは意図通りに設定されているか?(設定している場合)
  3. QMLツリー上でのアイテムの順序は、期待するタブ移動順序と一致しているか?
  4. enabledvisibleでアイテムが隠れていないか?
  5. Keysイベントハンドラで、デフォルトのフォーカス移動が邪魔されていないか?
  6. console.logやデバッガを使って、Item.nextItemInFocusChain()が実際に返すアイテムを検証する。


Item.nextItemInFocusChain()メソッドは、主にフォーカスチェーンのデバッグや、通常の自動的なフォーカス移動とは異なる複雑なキーボードナビゲーションを実装する際に役立ちます。通常、Qt Quickは非常に優れた自動フォーカス管理を提供するため、このメソッドを直接操作することは多くありません。

ここでは、その理解を深めるための具体的な使用例をいくつかご紹介します。

デフォルトのフォーカスチェーンを理解する

この例では、複数のTextInput要素を配置し、Tabキーを押したときにItem.nextItemInFocusChain()がどのアイテムを返すかを確認します。

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Focus Chain Debugging"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: textInput1
            placeholderText: "テキスト入力 1"
            width: 200
            focus: true // 最初にフォーカスを持つ
            Keys.onTabPressed: {
                var nextItem = textInput1.nextItemInFocusChain(true); // 順方向の次のアイテムを取得
                if (nextItem) {
                    console.log("textInput1 の次のアイテム (Tab):", nextItem.objectName || nextItem.id);
                } else {
                    console.log("textInput1 の次のアイテム (Tab): なし (チェーンの終端)");
                }
            }
            Keys.onShiftTabPressed: {
                var prevItem = textInput1.nextItemInFocusChain(false); // 逆方向の次のアイテムを取得
                if (prevItem) {
                    console.log("textInput1 の前のアイテム (Shift+Tab):", prevItem.objectName || prevItem.id);
                } else {
                    console.log("textInput1 の前のアイテム (Shift+Tab): なし (チェーンの終端)");
                }
            }
            objectName: "TextInput 1" // デバッグ用に名前を設定
        }

        TextInput {
            id: textInput2
            placeholderText: "テキスト入力 2"
            width: 200
            Keys.onTabPressed: {
                var nextItem = textInput2.nextItemInFocusChain(true);
                if (nextItem) {
                    console.log("textInput2 の次のアイテム (Tab):", nextItem.objectName || nextItem.id);
                } else {
                    console.log("textInput2 の次のアイテム (Tab): なし (チェーンの終端)");
                }
            }
            objectName: "TextInput 2"
        }

        TextInput {
            id: textInput3
            placeholderText: "テキスト入力 3"
            width: 200
            Keys.onTabPressed: {
                var nextItem = textInput3.nextItemInFocusChain(true);
                if (nextItem) {
                    console.log("textInput3 の次のアイテム (Tab):", nextItem.objectName || nextItem.id);
                } else {
                    console.log("textInput3 の次のアイテム (Tab): なし (チェーンの終端)");
                }
            }
            objectName: "TextInput 3"
        }

        Button {
            id: myButton
            text: "ボタン"
            Keys.onTabPressed: {
                var nextItem = myButton.nextItemInFocusChain(true);
                if (nextItem) {
                    console.log("myButton の次のアイテム (Tab):", nextItem.objectName || nextItem.id);
                } else {
                    console.log("myButton の次のアイテム (Tab): なし (チェーンの終端)");
                }
            }
            objectName: "Button"
        }
    }
}

解説

  • この例では、QMLツリーの視覚的な順序(上から下)に基づいてフォーカスが移動することを確認できます。
  • nextItemInFocusChain(true)は順方向(Tabキーの方向)の次のアイテムを、nextItemInFocusChain(false)は逆方向(Shift+Tabキーの方向)の次のアイテムを返します。
  • 同時に、各TextInputKeys.onTabPressedハンドラ内でnextItemInFocusChain(true)を呼び出し、デバッグコンソールに次にフォーカスが移るであろうアイテムのIDまたはobjectNameを出力しています。
  • このコードを実行し、textInput1にフォーカスがある状態でTabキーを数回押すと、各TextInputButtonがフォーカスを受け取ります。

nextItemInFocusプロパティとの連携(カスタムフォーカス順序)

nextItemInFocusChain()自体がフォーカスを制御するわけではありませんが、Item.nextItemInFocusプロパティで明示的にフォーカスチェーンを定義した場合に、それが正しく反映されているかをnextItemInFocusChain()で確認できます。

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Custom Focus Order"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: inputA
            placeholderText: "入力 A"
            width: 200
            focus: true
            nextItemInFocus: inputC // A -> C に直接移動
            objectName: "Input A"
            Keys.onTabPressed: {
                var next = inputA.nextItemInFocusChain(true);
                console.log("Input A の次のアイテム:", next ? (next.objectName || next.id) : "なし");
                event.accepted = false; // デフォルトのタブ動作を許可
            }
        }

        TextInput {
            id: inputB
            placeholderText: "入力 B"
            width: 200
            objectName: "Input B"
            Keys.onTabPressed: {
                var next = inputB.nextItemInFocusChain(true);
                console.log("Input B の次のアイテム:", next ? (next.objectName || next.id) : "なし");
                event.accepted = false;
            }
        }

        TextInput {
            id: inputC
            placeholderText: "入力 C"
            width: 200
            nextItemInFocus: inputB // C -> B に移動
            objectName: "Input C"
            Keys.onTabPressed: {
                var next = inputC.nextItemInFocusChain(true);
                console.log("Input C の次のアイテム:", next ? (next.objectName || next.id) : "なし");
                event.accepted = false;
            }
        }
    }
}

解説

  • このように、nextItemInFocusChain()は、明示的に設定されたnextItemInFocusプロパティがフォーカスチェーンにどのように影響するかを検証するのに役立ちます。
  • inputAにフォーカスがある状態でTabを押すと、inputCに移動します。その時、console.logにはinputCが出力されます。
  • 通常であればinputA -> inputB -> inputCの順にフォーカスが移動しますが、inputA.nextItemInFocus: inputCinputC.nextItemInFocus: inputBを設定することで、フォーカスチェーンをA -> C -> Bと変更しています。

特定の条件でフォーカスがどこへ行くべきかを判断するような、より複雑なシナリオでnextItemInFocusChain()の結果を基にカスタムロジックを実装する場合があります。

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Conditional Focus"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: mainInput
            placeholderText: "メイン入力"
            width: 200
            focus: true
            objectName: "Main Input"

            Keys.onTabPressed: {
                var defaultNext = mainInput.nextItemInFocusChain(true);
                console.log("Main Input のデフォルト次のアイテム:", defaultNext ? (defaultNext.objectName || defaultNext.id) : "なし");

                // もしデフォルトの次のアイテムが特定のものでなければ、別のアイテムに飛ばす
                if (defaultNext && defaultNext.id === specialButton.id) {
                    console.log("通常通り Special Button へ移動");
                    event.accepted = false; // デフォルトのタブ動作を許可
                } else {
                    // ここでは、もしデフォルトの次のアイテムが specialButton でない場合に、
                    // 強制的に finalTarget にフォーカスを移動させる例
                    console.log("Special Button 以外なので Final Target へ強制移動");
                    finalTarget.focus = true;
                    event.accepted = true; // デフォルトのタブ動作を抑制
                }
            }
        }

        Button {
            id: specialButton
            text: "特別なボタン"
            width: 200
            objectName: "Special Button"
        }

        TextInput {
            id: finalTarget
            placeholderText: "最終ターゲット"
            width: 200
            objectName: "Final Target"
        }
    }
}
  • このように、nextItemInFocusChain()は、複雑なUIロジックの中で「もし通常ならAにフォーカスが移るはずだが、特定の条件が満たされたらBにフォーカスを移したい」といったシナリオで、デフォルトの振る舞いを把握するために利用できます。
  • しかし、もしデフォルトの次のアイテムがspecialButtonでなければ(この例ではfinalTargetになるはずです)、意図的にfinalTarget.focus = true;としてフォーカスを強制的に移し、event.accepted = true;でデフォルトのタブ動作を抑制しています。
  • もしデフォルトの次のアイテムがspecialButtonであれば、通常通りspecialButtonにフォーカスを移動させます(event.accepted = falseでデフォルト動作を許可)。
  • この例では、mainInputからTabキーを押したときに、まずnextItemInFocusChain()デフォルトの次のアイテムが何かを調べます。


Item.nextItemInFocusChain()は、現在のアイテムから見て「次にフォーカスが移動するアイテムを問い合わせる」ためのメソッドであり、主にデバッグや複雑なフォーカスロジックを組む際の情報取得に用いられます。しかし、実際にフォーカスの移動を制御する場合、Qt Quickにはより直接的かつ一般的な代替手段が提供されています。

ここでは、その代替となる主要な方法をいくつかご紹介します。

Item.focus プロパティによる明示的なフォーカス設定

最も基本的で直接的な方法です。特定のアイテムにプログラムでフォーカスを移動させたい場合に用います。

説明
どのアイテムにフォーカスがあるかをQMLエンジンに伝えます。trueを設定されたアイテムがフォーカスを持ち、同時に他のアイテムからフォーカスが外れます。

使用例

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Explicit Focus"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: input1
            placeholderText: "入力 1"
            width: 200
            focus: true // アプリ起動時にフォーカスを持つ
        }

        TextInput {
            id: input2
            placeholderText: "入力 2"
            width: 200
        }

        Button {
            id: myButton
            text: "入力 2 にフォーカス"
            onClicked: {
                input2.focus = true; // ボタンがクリックされたら input2 にフォーカスを移動
                console.log("input2 にフォーカスが移動しました。");
            }
        }
    }
}

Item.nextItemInFocusChain()との比較
Item.nextItemInFocusChain()が「次にどこへ行くか」という情報を取得するのに対し、item.focus = trueは「ここにフォーカスを移動させる」という命令です。

Item.nextItemInFocus プロパティによるフォーカス順序のカスタマイズ

これは、タブキーによるフォーカス移動のデフォルトの順序を上書きするためのプロパティです。QMLツリーの視覚的な順序に依存しないカスタムなフォーカスチェーンを構築したい場合に非常に有効です。

説明
現在のアイテムからタブキーを押したときに、次にフォーカスが移動する先のアイテムを明示的に指定します。

使用例

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Custom Tab Order"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: textA
            placeholderText: "テキスト A"
            width: 200
            focus: true
            nextItemInFocus: textC // A の次は C
        }

        TextInput {
            id: textB
            placeholderText: "テキスト B"
            width: 200
            // nextItemInFocus の設定がない場合、QMLツリーの順序が適用される
            // ここでは textC の次 (もし textC.nextItemInFocus が設定されていなければ)
        }

        TextInput {
            id: textC
            placeholderText: "テキスト C"
            width: 200
            nextItemInFocus: textB // C の次は B
        }
    }
}

Item.nextItemInFocusChain()との比較
Item.nextItemInFocusChain()が特定の時点での計算結果(次にどこに行くか)を返すのに対し、nextItemInFocusは「次にどこに行くか」を定義するプロパティです。Item.nextItemInFocusChain()は、このnextItemInFocusの設定を考慮した上で結果を返します。

Keys.onTabPressed / Keys.onShiftTabPressed イベントハンドラによるカスタムナビゲーション

より複雑な条件に基づいてフォーカスを移動させたい場合や、特定のキーイベントに反応してフォーカス以外の動作も行いたい場合に利用します。

説明
TabキーまたはShift + Tabキーが押されたときに発生するイベントを捕捉し、その中で任意のQMLコードを実行できます。event.accepted = trueを設定することで、QMLのデフォルトのフォーカス移動処理を抑制できます。

使用例

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 400
    height: 300
    visible: true
    title: "Keys Event Handling"

    Column {
        spacing: 10
        anchors.centerIn: parent

        TextInput {
            id: usernameInput
            placeholderText: "ユーザー名"
            width: 200
            focus: true
            Keys.onTabPressed: {
                if (usernameInput.text.length < 3) {
                    console.log("ユーザー名が短すぎます。パスワードには移動しません。");
                    // エラーメッセージを表示するなど
                    event.accepted = true; // デフォルトのタブ移動を抑制
                } else {
                    passwordInput.focus = true; // パスワード入力へ移動
                    event.accepted = true; // デフォルトのタブ移動を抑制
                }
            }
        }

        TextInput {
            id: passwordInput
            placeholderText: "パスワード"
            width: 200
            Keys.onShiftTabPressed: {
                // パスワード入力から Shift+Tab で戻るとき、常にユーザー名入力に戻る
                usernameInput.focus = true;
                event.accepted = true; // デフォルトのタブ移動を抑制
            }
        }

        Button {
            text: "ログイン"
            width: 200
            // このボタンがフォーカスを持つことは想定しない(クリックで処理)
        }
    }
}

説明
FocusScopeは、その子アイテム間のフォーカス移動をカプセル化し、独立したフォーカスチェーンを持つようにするのに役立ちます。これにより、複雑なUI内でのフォーカス管理を簡素化できます。

使用例

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    width: 600
    height: 400
    visible: true
    title: "FocusScope Example"

    Row {
        spacing: 20
        anchors.centerIn: parent

        // グループ 1
        FocusScope {
            id: group1
            width: 250
            height: 200
            border.color: "lightgray"
            border.width: 1
            Column {
                spacing: 5
                anchors.centerIn: parent
                Text { text: "グループ 1" }
                TextInput { id: g1_input1; placeholderText: "G1入力 1"; focus: true; width: 180 }
                TextInput { id: g1_input2; placeholderText: "G1入力 2"; width: 180 }
                TextInput { id: g1_input3; placeholderText: "G1入力 3"; width: 180 }
            }
            nextItemInFocus: group2 // このグループの次は group2
        }

        // グループ 2
        FocusScope {
            id: group2
            width: 250
            height: 200
            border.color: "lightgray"
            border.width: 1
            Column {
                spacing: 5
                anchors.centerIn: parent
                Text { text: "グループ 2" }
                TextInput { id: g2_input1; placeholderText: "G2入力 1"; width: 180 }
                TextInput { id: g2_input2; placeholderText: "G2入力 2"; width: 180 }
            }
            nextItemInFocus: group1 // このグループの次は group1 (循環)
        }
    }
}

Item.nextItemInFocusChain()との比較
FocusScopeは、個々のアイテム間のフォーカスチェーンを管理するよりも、UIの論理的なグループに基づいてフォーカスチェーンを構造化するためのものです。Item.nextItemInFocusChain()は、FocusScope内のアイテム間、またはFocusScope自体と他のアイテム間のフォーカス移動を問い合わせる際に、その内部構造を考慮した結果を返します。

Item.nextItemInFocusChain()は、フォーカスの「次」を問い合わせる検査ツールのようなものですが、実際にフォーカスを制御し、アプリケーションのキーボードナビゲーションを実装するための主要な代替手段は以下の通りです。

  • FocusScope: フォーカス可能なアイテムのグループ化による、より分かりやすいフォーカス管理。
  • Keys.onTabPressed / Keys.onShiftTabPressed: 条件付きのフォーカス移動や、フォーカスイベントと連動するカスタムロジックの実装。
  • item.nextItemInFocus = anotherItem: デフォルトのタブ移動順序をカスタマイズ。
  • item.focus = true: プログラムによる直接的なフォーカス移動。