[pygtk] Focus on DrawingArea in TextView

Robert Schroll rschroll at gmail.com
Mon Mar 7 09:50:23 WST 2011


Hi all,

I'm trying to make a DrawingArea that's anchored in a TextView be able 
to receive keyboard focus.  I have the pieces - I can make a DrawingArea 
that's in a regular container grab focus on being clicked.  And I know 
that an Entry, e.g., can get focus when anchored in a TextView.  But I 
haven't been able to make that work for the anchored DrawingArea.

Below is test app that illustrates my problem.  I contains a TextView 
that has both a customized DrawingArea and an Entry.  When clicked, the 
DrawingArea is supposed to grab focus, and when it has focus, the 
DrawingArea is supposed to respond to key presses by drawing colored 
rectangles.  But the focus stays in the TextView even when I click on 
the DrawingArea.  In contrast, the Entry is happy to grab focus when 
clicked.  Below the TextView is a second customized DrawingArea, which 
displays the behavior I want.

Any hints on how to make this work?  Thanks,
Robert

----
import gtk

class FocusArea(gtk.DrawingArea):
     def __init__(self):
         gtk.DrawingArea.__init__(self)
         self.set_size_request(50,50)
         self.set_can_focus(True)
         self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.KEY_PRESS_MASK)
         self.connect('key_press_event', self._on_key_press_event)
         self.connect('button_press_event', self._on_button_press)

     def _on_key_press_event(self, widget, event):
         color = {'r': '#f00', 'y': '#ff0', 'g': '#0f0', 'c': '#0ff', 
'b': '#00f',
                  'm': '#f0f'}.get(event.string, '#000')
         gc = self.window.new_gc()
         gc.set_foreground(self.get_colormap().alloc_color(color))
         self.window.draw_rectangle(gc, True, 10, 10, 30, 30)

     def _on_button_press(self, widget, event):
         print "Click!"
         self.grab_focus()

view = gtk.TextView()
buf = view.get_buffer()
view.set_size_request(300,300)

buf.insert_at_cursor("Doesn't get focus: ")
iter = buf.get_iter_at_mark(buf.get_insert())
anchor = buf.create_child_anchor(iter)
widget = FocusArea()
widget.show()
view.add_child_at_anchor(widget, anchor)

buf.insert_at_cursor("\nDoes get focus: ")
iter = buf.get_iter_at_mark(buf.get_insert())
anchor = buf.create_child_anchor(iter)
widget = gtk.Entry()
widget.show()
view.add_child_at_anchor(widget, anchor)

da = FocusArea()

vbox = gtk.VBox()
vbox.pack_start(view, True, True)
vbox.pack_start(da, True, True)

win = gtk.Window()
win.add(vbox)
win.connect("delete-event", gtk.main_quit)
win.show_all()

gtk.main()


More information about the pygtk mailing list