calling a Frame from a Dialog

Hi,

in my Program I need to call a Frame from a Dialog.
It seems to be possible to create the Frame, but I can not close it anymore.

If I instead call a Dialog2 from the Dialog1, there are no problems.

What am I doing wrong? Or is it just not possible?

Thanks!
Leon

example_callFrameFromDialog.py (2.5 KB)

Leon wrote:

in my Program I need to call a Frame from a Dialog.
It seems to be possible to create the Frame, but I can not close it
anymore.

If I instead call a Dialog2 from the Dialog1, there are no problems.

What am I doing wrong? Or is it just not possible?

What operating system are you using? On Windows, I was able to close
your frame just fine with the "X" close button.

However, there are other problems with your code. You are invoking your
dialog with "ShowModal". That starts its own message loop, essentially
putting the rest of the UI on hold until the dialog closes. ShowModal
won't return until the dialog box has closed, so when you call
SetTopWindow, the window is already gone, which triggers an error. You
never get to your "MainLoop" at all.

If you change ShowModal to Show, it should all work.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,
that was exactly the problem. Thank you very much!
Operating system was Kubuntu :slight_smile:

···

Am Donnerstag, 1. September 2016 20:08:28 UTC+2 schrieb Tim Roberts:

Leon wrote:

in my Program I need to call a Frame from a Dialog.

It seems to be possible to create the Frame, but I can not close it

anymore.

If I instead call a Dialog2 from the Dialog1, there are no problems.

What am I doing wrong? Or is it just not possible?

What operating system are you using? On Windows, I was able to close

your frame just fine with the “X” close button.

However, there are other problems with your code. You are invoking your

dialog with “ShowModal”. That starts its own message loop, essentially

putting the rest of the UI on hold until the dialog closes. ShowModal

won’t return until the dialog box has closed, so when you call

SetTopWindow, the window is already gone, which triggers an error. You

never get to your “MainLoop” at all.

If you change ShowModal to Show, it should all work.


Tim Roberts, ti...@probo.com

Providenza & Boekelheide, Inc.

ok, not quite :frowning:
If I want the Dialog to return some user response, I need to call it via “ShowModal”.
But if I do that, I can not close the Frame anymore.
Has anybody got an idea?

···

Am Freitag, 2. September 2016 10:01:22 UTC+2 schrieb Leon:

Hi Tim,
that was exactly the problem. Thank you very much!
Operating system was Kubuntu :slight_smile:

Am Donnerstag, 1. September 2016 20:08:28 UTC+2 schrieb Tim Roberts:

Leon wrote:

in my Program I need to call a Frame from a Dialog.

It seems to be possible to create the Frame, but I can not close it

anymore.

If I instead call a Dialog2 from the Dialog1, there are no problems.

What am I doing wrong? Or is it just not possible?

What operating system are you using? On Windows, I was able to close

your frame just fine with the “X” close button.

However, there are other problems with your code. You are invoking your

dialog with “ShowModal”. That starts its own message loop, essentially

putting the rest of the UI on hold until the dialog closes. ShowModal

won’t return until the dialog box has closed, so when you call

SetTopWindow, the window is already gone, which triggers an error. You

never get to your “MainLoop” at all.

If you change ShowModal to Show, it should all work.


Tim Roberts, ti...@probo.com

Providenza & Boekelheide, Inc.

Leon wrote:

If I want the Dialog to return some user response, I need to call it
via "ShowModal".
But if I do that, I can not close the Frame anymore.
Has anybody got an idea?

Return a response to who? In the example you posted, the dialog is
being presented before any windows are visible. There's no one to
receive the response.

If the dialog really is the main window for the app -- which is a
perfectly valid thing to do -- then you don't return a response. You
just have the onOK or onCancel handlers in the dialog do whatever needed
to be done.

Why do you need another frame? Is this a case where you could have the
extra information in the dialog hidden, and when you need to show it you
just increase the width?

If you really are calling this dialog from another window, then you can
leave it modeless (Show instead of ShowModal), and have the dialog send
a response back to its parent asynchronously, either using
parent->QueueEvent or CallAfter.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

thanks for trying to help me. But I still do not get it!
Yes, in my real program, I start with a Frame which calls a Dialog. This dialog then calls Frame2.
I have adjusted my example.
I have also tried to implement CallAfter:
I try to call the function “printValue”, after the Dialog is closed.
But it seems to be called to early: the variable is not yet defined :frowning:

Maybe I need to wait until the Dialog is closed? But how?

example_callFrameFromDialog.py (3.06 KB)

···

Am Freitag, 2. September 2016 22:43:19 UTC+2 schrieb Tim Roberts:

Leon wrote:

If I want the Dialog to return some user response, I need to call it

via “ShowModal”.

But if I do that, I can not close the Frame anymore.

Has anybody got an idea?

Return a response to who? In the example you posted, the dialog is

being presented before any windows are visible. There’s no one to

receive the response.

If the dialog really is the main window for the app – which is a

perfectly valid thing to do – then you don’t return a response. You

just have the onOK or onCancel handlers in the dialog do whatever needed

to be done.

Why do you need another frame? Is this a case where you could have the

extra information in the dialog hidden, and when you need to show it you

just increase the width?

If you really are calling this dialog from another window, then you can

leave it modeless (Show instead of ShowModal), and have the dialog send

a response back to its parent asynchronously, either using

parent->QueueEvent or CallAfter.


Tim Roberts, ti...@probo.com

Providenza & Boekelheide, Inc.

Leon wrote:

thanks for trying to help me. But I still do not get it!
Yes, in my real program, I start with a Frame which calls a Dialog.
This dialog then calls Frame2.
I have adjusted my example.
I have also tried to implement CallAfter:
I try to call the function "printValue", after the Dialog is closed.
But it seems to be called to early: the variable is not yet defined :frowning:

Yes, you haven't thought about what this does. Show() is going to
return immediately. You then immediately try to fetch "userinput" to
pass to CallAfter, but the dialog hasn't even been displayed yet, so
naturally the value does not exist.

There are two choices. The way you have it now, as soon as
OnButton1Button returns, your frame no longer has any way to contact the
dialog, because you don't have a reference to it. Thus, there is no way
for you to ask it for information, even if you knew when it was done.
Thus, you will need to have the dialog be in charge. Right now, you are
passing "None" as the parent of Dialog1. That's wrong -- the frame is
the parent -- and that makes it impossible to get any back
communication. Instead, pass the frame as the parent, and hand the
dialog a function for it to call when it is done:

    def OnButton1Button( self, event ):
        myDialog1 = Dialog1( self, self.printValue )
        myDialog1.Show()
        event.Skip()

Now the dialog has what it needs to notify the parent when it is done:

class Dialog1(wx.Dialog):
    ...
    def __init__(self, parent, callme):
        self.notify= callme
        self._init_ctrls(parent)
   ...
    def OnDialog1Close(self, event):
        self.notify( 'Hello' )
        self.Destroy()
        event.Skip()

The other alternative is to store the dialog in a member variable
instead of a local variable, but then you still have the problem of
knowing when the dialog is complete.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

yes, that works!
Thank you!

···

Am Dienstag, 6. September 2016 18:44:04 UTC+2 schrieb Tim Roberts:

Leon wrote:

thanks for trying to help me. But I still do not get it!

Yes, in my real program, I start with a Frame which calls a Dialog.

This dialog then calls Frame2.

I have adjusted my example.

I have also tried to implement CallAfter:

I try to call the function “printValue”, after the Dialog is closed.

But it seems to be called to early: the variable is not yet defined :frowning:

Yes, you haven’t thought about what this does. Show() is going to

return immediately. You then immediately try to fetch “userinput” to

pass to CallAfter, but the dialog hasn’t even been displayed yet, so

naturally the value does not exist.

There are two choices. The way you have it now, as soon as

OnButton1Button returns, your frame no longer has any way to contact the

dialog, because you don’t have a reference to it. Thus, there is no way

for you to ask it for information, even if you knew when it was done.
Thus, you will need to have the dialog be in charge. Right now, you are

passing “None” as the parent of Dialog1. That’s wrong – the frame is

the parent – and that makes it impossible to get any back

communication. Instead, pass the frame as the parent, and hand the

dialog a function for it to call when it is done:

def OnButton1Button( self, event ):

    myDialog1 = Dialog1( self, self.printValue )

    myDialog1.Show()

    event.Skip()

Now the dialog has what it needs to notify the parent when it is done:

class Dialog1(wx.Dialog):

...

def  __init__(self, parent, callme):

    self.notify= callme

    self._init_ctrls(parent)

def OnDialog1Close(self, event):

    self.notify( 'Hello' )  
    self.Destroy()

    event.Skip()

The other alternative is to store the dialog in a member variable

instead of a local variable, but then you still have the problem of

knowing when the dialog is complete.


Tim Roberts, ti...@probo.com

Providenza & Boekelheide, Inc.