calling a Frame from a Dialog

59 views
Skip to first unread message

Leon

unread,
Sep 1, 2016, 11:23:51 AM9/1/16
to wxPython-users
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

Tim Roberts

unread,
Sep 1, 2016, 2:08:28 PM9/1/16
to wxpytho...@googlegroups.com
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

unread,
Sep 2, 2016, 4:01:22 AM9/2/16
to wxPython-users
Hi Tim,
that was exactly the problem. Thank you very much!
Operating system was Kubuntu :)

Leon

unread,
Sep 2, 2016, 2:50:32 PM9/2/16
to wxPython-users
ok, not quite :(
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?

Tim Roberts

unread,
Sep 2, 2016, 4:43:19 PM9/2/16
to wxpytho...@googlegroups.com
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.

Leon

unread,
Sep 3, 2016, 5:17:29 AM9/3/16
to wxPython-users
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 :(

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

Tim Roberts

unread,
Sep 6, 2016, 12:44:04 PM9/6/16
to wxpytho...@googlegroups.com
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 :(

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.

Leon

unread,
Sep 7, 2016, 5:53:14 AM9/7/16
to wxPython-users
yes, that works!
Thank you!
Reply all
Reply to author
Forward
0 new messages