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:
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:
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
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