On Friday 18 September 2009, Eric Hutton wrote:> Hi all,
>
> Almost have my data import code doing what I want it to, but I seem to be
> having an issue with delays in the creation of some widgets.
>
> What I''m trying to do is have a dialog box that pops up to let the
user know
> that the data import is occurring, and what stage the process is at. The
> problem is that the while the dialog box gets drawn, none of the widgets
get
> drawn until after all the data import tasks have been done. I have tried
to
> force the creation using recalc, repaint, layout, but nothing seems to be
> doing the trick.
>
> My code looks like this:
> if find_customs_file.execute != 0 # get the result from the users
> selection from a FXFileDialog Box
> customs_import_dialog = File_Import_Dialog.new(self) # a
> sublcass of FXDialogBox
> customs_import_dialog.create
> customs_import_dialog.show(PLACEMENT_SCREEN)
> print "working"
> customs_data = File.readlines(find_customs_file.filename)
> print "done"
> end
>
> So I tried inserting customs_import_dialog.update, or layout, or repaint in
> there before the call to File.readlines, but nothing helped.
>
> The print statements help me track what is going on. Right now the
> File_Import_Dialog window will get drawn, but with no widgets..
"working"
> shows up, still no widgets... big pause while the file is imported, then
> "done" shows up, and finally the full File_Import_Dialog box
shows up...
> which kind of defeats the purpose (that of telling the user something along
> the lines of "hi there, hold on while I import this file,
it''s a big one and
> could take awhile"). I can''t tell for certain, but I think
the widgets are
> actually drawn after the "print "done" " statement, and
only occurs at the
> time the "if" statement ends.
That is correct. Drawing will get done only when the system gets to an
event loop, and processes out-standing redraw events.
To get it to do this BEFORE your callback returns, you must recursively
enter the event loop (presumably, block further user input while in that
subloop and only process non-input type events).
The good news is that this is possible: runModalWhileEvents() is what
you want to call; I suggest calling it during a long-winded file I/O
operation as well, so the screen has a chance to refresh.
The idea is to handle a bunch of events until the event queue is empty, and
then return to the the file import code. You can invoke runModalWhileEvents()
repeatedly, if there is a reason to assume more events have arrived that need
to be handled.
When you first popup a dialog, there is a lot of back-and-forth between X11
server and the application, to resize and redraw items just put on the screen;
after that bunch of events has been handled, things kind of come to a rest and
the window is ready for business.
Note, it works better in FOX 1.7 because this function now as a parameter
to block for a little while, prior to returning with an empty event queue.
The suggestion from Meinrad Recheis is good too, but this is definitely more
complex; but multi-threading may be overkill for this particular situation.
- Jeroen