tags:

views:

217

answers:

3

I'm new to Python and I'm trying to create a simple GUI using Tkinter. So often in many user interfaces, hitting the tab button will change the focus from one text box to another. Whenever I'm in a text widget, tab only indents the text cursor.

Does anyone know if this is configurable? If not, can PyQt or any other Python UI framework offer this functionality?

A: 

Due to the cross platform nature, the focus traversal is somewhat customizable, usually letting the X windows manager handle it (with focus follows mouse, or click). According to the manual it should be possible to bind an event to the key press event, scanning for tab presses, and triggering a focusNext event in those cases.

dlamblin
I don't get it; I suggested exactly what http://stackoverflow.com/users/7432/bryan-oakley wrote in his accepted answer http://stackoverflow.com/questions/1450180/how-can-i-change-the-focus-from-one-text-box-to-another-in-python-tkinter/1451343#1451343 didn't I?
dlamblin
A: 

Not sure about TKinter, but with PyQt, one can connect a function to the tab changed signal emitted by the tab box(the signal also carries an int value). But as far as I am aware Qt is pretty good at doing the right thing without it being specified.

Chazadanga
+1  A: 

This is very easy to do with Tkinter.

There are a couple of things that have to happen to make this work. First, you need to make sure that the standard behavior doesn't happen. That is, you don't want tab to both insert a tab and move focus to the next widget. By default events are processed by a specific widget prior to where the standard behavior occurs (typically in class bindings). Tk has a simple built-in mechanism to stop events from further processing.

Second, you need to make sure you send focus to the appropriate widget. There is built-in support for determining what the next widget is.

For example:

def focus_next_window(event):
    event.widget.tk_focusNext().focus()
    return("break")

text_widget=Text(...)
text_widget.bind("<Tab>", focus_next_window)

Important points about this code:

  • The method tk_focusNext() returns the next widget in the keyboard traversal hierarchy.
  • the method focus() sets the focus to that widget
  • returning "break" is critical in that it prevents the class binding from firing. It is this class binding that inserts the tab character, which you don't want.

If you want this behavior for all text widgets in an application you can use the bind_class() method instead of bind() to make this binding affect all text widgets.

You can also have the binding send focus to a very specific widget but I recommend sticking with the default traversal order, then make sure the traversal order is correct.

Bryan Oakley