2

一連のテキスト コントロールを含むカスタム ダイアログを作成しました。すべてのテキスト コントロールには、特定の値をより便利に追加するためのいくつかのボタンが横にあります。ほとんどの場合、ユーザーはボタンを使用する必要がないため、ユーザーがダイアログをタブで移動するときに、これらのボタンにフォーカスを与えたくありません。

特定のコントローラーを標準のタブ トラバーサルから除外する便利な方法はありますか?

4

3 に答える 3

3

ボタンがキーボードでフォーカスされないようにする簡単な方法は、以下のオーバーライドをサポートするものから派生するwx.lib.buttons.GenButtonか、wx.lib.buttons.ThemedGenButtonそれに基づいています。wx.PyControlAcceptsFocusFromKeyboard()

class NoFocusButton(wx.lib.buttons.ThemedGenButton):
    def __init__(self, parent, id=wx.ID_ANY, label=wx.EmptyString, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=wx.ButtonNameStr):
        wx.lib.buttons.ThemedGenButton.__init__(self,parent,id,label,pos,size,style,validator,name)
    def AcceptsFocusFromKeyboard(self):
        return False # does not accept focus

より複雑なナビゲーションルールまたはコントロールの場合はwx.EVT_NAVIGATION_KEY、ナビゲーションを自分で処理および管理できます。ナビゲートするウィンドウのリストを取得するには、を使用できますself.GetChildren()。で現在フォーカスされているウィンドウのインデックスは、wx.WindowListを介して取得できます.index(mywindow)。その情報を使用して、ユーザーが「ナビゲーションキー」を押すたびにリストをナビゲートし、フォーカスしたくないコントロールをスキップして、フォーカスを次の該当するコントロールに設定できます。

リスト内を簡単に移動できるように、ジェネレーターを作成できます。

def CycleList(thelist,index,forward):
    for unused in range(len(thelist)): # cycle through the list ONCE
        if forward:
            index = index+1 if index+1 < len(thelist) else 0
        else:
            index = index-1 if index-1 >= 0 else len(thelist)-1
        yield thelist[index]

ダイアログで、次を処理しwx.EVT_NAVIGATION_KEYます。

self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavigationKey)
def OnNavigationKey(self,event):
    children = self.GetChildren() # list of child windows
    focused = self.FindFocus()    # current focus

    # avoid accessing elements that do not exist
    if not focused or focused not in children:
        event.Skip() # use default behavior
        return

    index = children.index(focused)

    for child in CycleList(children,index,event.GetDirection()):
        # default behavior:
        if child.AcceptsFocusFromKeyboard():
            child.SetFocus()
            return

上記の例は、デフォルトの動作をエミュレートします。フォーカス可能なコントロールを循環します(静的テキストなどのフォーカスできないコントロールをスキップします)。AcceptsFocusFromKeyboardチェックを拡張して特定のコントロールを除外したり、 Falseを返すことを実装するカスタムボタンクラスを作成したりできます。

注:wx.PyWindow、、wx.PyPanelおよびwx.PyControlのオーバーライドを許可するメカニズムを実装している間、AcceptsFocusFromKeyboard標準のwxPythonコントロールはそうではありません。ただし、Python側での処理wx.EVT_NAVIGATION_KEYとチェックは、オーバーライドされたメソッドを呼び出す実際のPythonオブジェクトにアクセスします。AcceptsFocusFromKeyboard

于 2013-01-28T12:29:15.587 に答える
0

C ++を使用している場合、この回答の残りの部分で説明されているように、この問題には簡単な解決策があります。wxPythonでは、wxWidgetsクラスを特殊化できないようです。これは私には致命的な問題のようです。

AcceptsFocusFromKeyboard()をオーバーライドしてFALSEを返すことにより、タブトラバーサルから除外されるボタンコントロールの特殊化を作成できます。

http://docs.wxwidgets.org/trunk/classwx_window.html#a2370bdd3ab08e7ef3c7555c6aa8301b8

次のC++コードは正常に機能します。タブを押すと、フォーカスが最初のボタンから3番目のボタンにジャンプします。

class cNoTabButton : public wxButton
{
public:
    cNoTabButton(wxWindow *parent,
             wxWindowID id,
             const wxString& label = wxEmptyString,
             const wxPoint& pos = wxDefaultPosition,
             const wxSize& size = wxDefaultSize,
             long style = 0 )
             : wxButton(parent,id,label,pos,size,style)
    {}
    bool AcceptsFocusFromKeyboard() const { 
        return false;
    }
};

MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
    // set the frame icon
    SetIcon(wxICON(sample));

    wxPanel * panel = new wxPanel(this,-1,wxPoint(0,0),wxSize(500,500));

    new wxButton(panel,-1,"TabPlease",wxPoint(20,20));
    new cNoTabButton(panel,-1,"NoTabThanks",wxPoint(100,20));
    new wxButton(panel,-1,"OKWithMe",wxPoint(200,20));


}
于 2013-01-22T14:45:10.393 に答える