Question

I'm rewriting an already working application from the ground up, and a couple of modules in I hit a curious snag. At present, the only thing it does is read in CSV file into a dictionary, set up the GUI, and write the dictionary back to CSV. The GUI is supposed to open document windows for selections of the items in the dictionary as they are asked for: at present I just want it to open a window for all items when I press Return.

Yesterday it worked like it should. Today I made some changes to the CSV read/save commands, and suddenly the main window isn't responding any more. I have an exact diff of the changes, and none of them should affect the event handling.

The bindings look like this:

bind . <Escape> {exec wish $argv0 &; exit}
bind . <?> {catch {console show} ; ::log::lvSuppressLE warning 0}
bind . <Return> IDB::GUI::openwindow

I've looked on SO, on the wiki, and searched the web, but if this has been discussed before I seem to have missed it. I've tried, among other things, calling update and using bindtags to prioritize my bindings. None of this works, but if I add this after the bindings:

tk_messageBox -message foo

it works like a charm: all the bindings fire when I press the keys. Obviously the message box clears up something that is blocking the event delivery, but I can't figure out what it is.

I would very much like to avoid posting a nonsense message box just to get my application to respond.

And don't tell me God is punishing me for working on Good Friday.

ETA: it seems that a message box after setting up the GUI isn't sufficient, I need one before setting it up too. When I removed that one, the events stopped working again.

Edit after getting an answer: a simple focus . seems to be sufficient to keep my main window responsive. For good measure, I added another binding, bind . <Button-1> {focus .}, which I hope will enable me to restore focus if something diverts it again. I may also add some focus introspection to my application logging.

(Edit of the edit: of course, if one puts in the binding bind . <Button-1> {focus .} it helps immensely to remember to take it out once one starts adding e.g. entry widgets to the GUI: otherwise one might wonder briefly why one's entries don't get focus when they are clicked on. Simple? Of course I am.)

As Donal points out, <?> isn't a valid event code (it should be something like <Key-question>). It works for me, but if you decide to reuse that particular binding, bear in mind that it isn't in any way guaranteed to work for you.

Était-ce utile?

La solution

It sounds like your main window simply doesn't have the keyboard focus. Popping up the messagebox and then dismissing it probably has the side effect of setting focus to the main window.

Try explicitly setting focus on ..

Autres conseils

The most likely problems are either that you've not got the focus where you expect, or that you've got a break bubbling out of a binding that you didn't expect (since bindings on . are typically pretty low priority).

If you know where the focus is (and it's where you think it should be!) then check the bindtags and the list of bindings on each of those bindtags. Here's how to see everything

set w [focus]
puts "For window $w..."
foreach tag [bindtags $w] {
    foreach sequence [bind $tag] {
        puts [list bind $tag $sequence [bind $tag $sequence]]
    }
}

Also watch out for what virtual events are mapped to; event info <<TheVirtualEvent>> will tell you what real keys trigger it. (There's a complex interaction between real and virtual events when they're both trying to handle the same actual event; I can never safely predict what happens there, and try to avoid it.) Not all virtual events necessarily have any key bindings; some are just issued directly with event generate from code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top