Sequence of events when starting Dialog changed from2.6 to 2.8

Hi Werner,

Thanks for the response.

Hi Frank,

Frank Millman wrote:

Hi all

Attached is a simple program. There is a frame with a button. Clicking

the

button launches a dialog. I want to add various steps while setting up

the

dialog, so I have the following -

    def onClick(self, evt):
        self.dlg = MyDialog(self)
        wx.CallAfter(self.showDlg)
        wx.CallAfter(self.startDlg)

    def showDlg(self):
        self.dlg.ShowModal()
        self.dlg.Destroy()

    def startDlg(self):
        self.dlg.t1.SetFocus()

This works with MSW, and it worked with GTK2 using wxPython 2.6 (I

skipped

2.7).

With 2.8, startDlg() is only called after the dialog is destroyed, which

is

obviously too late for my purposes.
  
I am surprised that this worked in 2.6 as you are calling startDlg after
showDlg and it contains Destroy.

As I understand it, I am queuing the calls to showDlg and startDlg, but it
is the wx main loop that actually does the calls. Therefore I think the
sequence of events is like this -

1. onClick creates the dialog and queues the two method calls.
2. MainLoop calls showDlg, which calls ShowModal.
3. MainLoop calls startDlg, which sets focus on t1.

Hopefully Robin will correct me if I have got this wrong.

I always use try/finally with dialogs, to ensure that they get destroyed
whatever happens with the dialog

   def onClick(self, evt):
       try:
           self.dlg = MyDialog(self)
           self.startDlg()
       finally:
           self.dlg.Destroy()

   def startDlg(self):
       self.dlg.t1.SetFocus()
       self.dlg.ShowModal()

This makes sense, and I could probably refactor my program to work in this
way, but I would lose some flexibility. I have a client/server architecture.
wx is the client, and it reacts to messages received from the server. The
server sends a message to create the dialog, followed by a series of
messages to set up the controls, followed by a message to show the dialog.
Then there could be some messages to populate some of the controls. When all
is ready, it sends a message to start the dialog. I have to use CallAfter as
the messages are received in a different thread.

The reason why showDlg and startDlg are separate is that the dialog can be
used for data capture, in which case, after the user saves the contents of
the form, the server can send a message to clear the fields and restart the
dialog, but there is no need to reshow it.

Maybe you would also want to do the setfocus in the dialog init or in a

function in

the dialog which you then call, e.g.:

   def onClick(self, evt):
       try:
           self.dlg = MyDialog(self)
           self.dlg.startDlg()
    self.dlg.ShowModal()
       finally:
           self.dlg.Destroy()

My present architecture has evolved into its present shape, but it is not
necessarily ideal. I will wait to see what Robin has to say, but if there is
no easy solution I will have to restructure my approach. I may have to store
up all the messages on the client and execute them all together when I
receive the 'start dialog' message. It could then end up looking something
like your suggestion.

Thanks for the ideas.

Frank