wxpython and EVT_KILL_FOCUS

S

Stefanie Wagner

Hello, I am fighting with EVT_KILL_FOCUS for quite a time now and I
don't succeed at all.

Situation:

If a user leaves a textfield the entered information should be checked
and an additional window should be opened to make a search possible to
complete the entry.

Basic solution:

def __init__(...):
...
self.artikelnrBox = wxTextCtrl(self.bestelldialog, -1, artikelnr,
wxPoint(60,290), wxSize(60, -1))
...
EVT_KILL_FOCUS(self.artikelnrBox, self.OnArtikel)
...

def OnArtikel(self,event):
event.Skip()
....
artikelnr = self.artikelnrBox.GetValue().strip()
...
dialog =
dialog_stamm_artikel.ArtikelSucheDialog(self.bestelldialog,artikelnr)
ergebnis,artikelid = dialog.GetValues()
dialog.Destroy()
...

Problem:

If I don't open any dialog everything works fine. But if there is a
dialog around the window opens, I can count to two and the whole
application crashes.

The error message is:
(gui.py:29768): Gtk-WARNING **: GtkEntry - did not receive
focus-out-event. If you
connect a handler to this signal, it must return
FALSE so the entry gets the event as well

Gtk-ERROR **: file gtkentry.c: line 4919 (blink_cb): assertion failed:
(GTK_WIDGET_HAS_FOCUS (entry))
aborting...

Reason of the problem:

I found a very good description for the reason:
This is a lot easier to understand with a timeline:
- focus into GtkEntry
- GtkEntry installs timeout for cursor blinking
- focus out of entry
- GtkEntry emits focus-out-event
- your handler runs **before the default handler**.
- your handler traps exception and creates dialog box
- dialog box runs nested event loop
- event processing continues, focus goes to another widget
- entry's cursor blink timeout is still installed, and runs again.
entry does not have focus, but timeout has run, so the widget
is in an invalid state and calls g_error() with a nastygram.
- default handler runs, uninstalls cursor blink timeout
The problem is that you're allowing the event loop to run in your handler for focus-out.

Ok, if I use EVT_KILL_FOCUS the event has not finished completly, this
timeout is still around. That's ok with me but I thought this is what
event.Skip() is for, to call the standard handler.

Solution:

And there I am. event.Skip() doesn't help at all. And the other source
gives the following suggestion:
a) use signal_connect_after to have your handler run *after* the default handler for focus-out-event instead of before.
b) leave the signal connected normally, but in your "catch" block, instead of running the dialog right then, defer it with an idle, like this:

I couldn't find signal_connect_after anywhere in wxpython and I don't
know how to use idle in this case. And I have the problem more than
once (every time a have an error message in other EVT_KILL_FOCUS
routines).

There must be some solution to use EVT_KILL_FOCUS and a dialog without
killing the application.

Please help!

Steffi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,133
Latest member
MDACVReview
Top