Sunday, August 05, 2012

Problem with after_idle

I ran into a bug with ebe recently which occurred under Debian Squeeze.  When ebe was started it "flashed" the menubar preventing it from working.  The same source code worked well under Ubuntu so I started looking for the problem.

I installed virtualbox on my home computer and installed Squeeze and sure enough the problem was there in the virtual Squeeze.  The likely problems seemed to be python, tkinter or pmw.  After some effort I managed to configure apt to allow installing packages from the testing repository.  I installed newer versions of python and pmw which were pretty much the same versions as I had on Ubuntu.  Still the problem persisted.

Now I knew that I was writing the line and column number of the editing cursor in the menubar in ebe, so I figured there might be some chance that I had screwed up that code.  I searched and located that all over the place in ebe I used after_idle to call a function which updated the line and column information on the menubar.  It looked like the problem was corralled.

I reread the documentation about the Tkinter after_idle function.  It claimed that after_idle would call a function once for a call to after_idle.  It seemed to me that after_idle was continuing to call my function to show the location.  This could happen if the location update code called after_idle or if after_idle was broken.

It turned out that after_idle was being called as a result of using my location update code.  I didn't locate a place where it could have happened and the fact that the code worked on Ubuntu and Windows makes it seem that the best bet was a problem with after_idle.  I realize that problems can occasionally make little sense and certainly studying the Tkinter code was beyond the call of duty, so I decided to solve the problem without figuring out exactly why the problem ever showed up.

The solution was pretty simple.  I added an additional function, show_location1, which I interposed between show_location which calls after_idle and show_location2 which actually does the location updates.  I am now using after_idle to call show_location1 and show_location1 calls after to trigger a call to show_location2 after 500 msecs.  The problem still exists, but updating the location twice a second doesn't interfere with the normal operation of ebe.

My expectation is that this is not a problem with my code, but I am not certain.  It makes me think that perhaps I would have been better off using QT with C++ rather than python.  Who knows which would cause the least trouble?

No comments: