From: Kevin A. <al...@se...> - 2004-09-15 01:16:31
|
On Sep 14, 2004, at 5:33 PM, Alex Tweedly wrote: > At 11:04 14/09/2004 -0700, Kevin Altis wrote: > >> There didn't seem to be any major objections, so I went ahead and >> checked in the Notebook component, the necessary changes to the >> framework, and a testNotebook sample. The changes should show up on >> anonymous cvs later this afternoon. See my other comments below. > > Not sure if it's better to cc the whole list on these messages while I > stumble around trying the Notebook component or not - might save > others repeating the same sequence, so I'll do that for now, and take > it off-list if this goes on too long. > > Aim - build a program that uses a tabbed notebook to display multiple > csv files; each time you do File/Open, it creates a new tab and > displays the file in it. > > First, I built a very simple csv-viewer program (one component, a > multicolumn list), and only filled in the FIle/Open handler, to get a > file name, then call on_openFile to read in the csv file and display > it. > > Then I changed that from a stand-alone program to make it ready for > inclusion in a notebook (i.e. I changed it from model.Background to > model.PageBackground). > > Then I built another very simple app (one component - a notebook), but > didn't put anything into the notebook in on_initialize; and I made its > on_openFile do the following : > > win = model.childWindow(self.components.myNotebook, > csv_page.csvPage) > self.components.myNotebook.AddPage(win, pageName, True) > win.openFile(path) > > i.e. create the window, add it to the notebook, then invoke the > openFile handler, passing in the filename to read ..... > > It kind of works - it displays the data from the csv file in a > multicolumnlist inside the notebook; and if I open another file, it > opens a new tab, and displays it. > > BUT there is a problem - I get errors because some variables within > the csvPage don't exist. > Adding some debug "print"s, I found that the on_openfile seems to be > called before the on_initialize. > It looks as though the on_initialize is being called later (maybe from > wxMainLoop) > > Does that make any sense ? > Or should I go back and look for other causes for why things seem to > be called in the "wrong" order ? > That is the expected behavior. initialize is an event that is posted when PageBackground is created. However, you don't give it a chance to run until after win.openFile(path) because you are still in the event where you are creating the window and adding it to the notebook. So, you have a couple of options besides making your own __init__ method in your PageBackground subclass, which is a little complicated. The simplest is probably just to change the last line to wx.CallAfter(win.openFile, path) Once the event message queue empties, openFile will be called and that should be after on_initialize runs. Additional technical details... Due to event order when windows are created, some events such as size, move, gainFocus, or idle may also occur before initialize. Linux/GTK seems particularly bad about this and I have never figured out a good workaround. In cases like that you have to use some protection code to avoid doing some operation before proper initialization has occurred. That might be as simple as something like: if not hasattr(self, 'path'): event.skip() return Where the assumption is that self.path would be created in your on_initialize handler. I suggest running the testvents sample application. I may have to explicitly bind the gainFocus event separately from all the other events to fix that particular problem. I have left it alone so far because gainFocus just isn't used; the only sample or tool that uses it is testevents. ka |