views:

987

answers:

2

Is is possible to make a wxFrame object behave like a modal dialog box in that the window creating the wxFrame object stops execution until the wxFrame object exits?

I'm working on a small game and have run into the following problem. I have a main program window that hosts the main application (strategic portion). Occasionally, I need to transfer control to a second window for resolution of part of the game (tactical portion). While in the second window, I want the processing in the first window to stop and wait for completion of the work being done in the second window.

Normally a modal dialog would do the trick but I want the new window to have some functionality that I can't seem to get with a wxDialog, namely a status bar at the bottom and the ability to resize/maximize/minimize the window (this should be possible but doesn't work, see this question How to get the minimize and maximize buttons to appear on a wxDialog object).

As an addition note, I want the second window's functionality needs to stay completely decoupled from the primary window as it will be spun off into a separate program eventually.

Has anyone done this or have any suggestions?

+1  A: 

It does not really make sense to "stop execution" of a window, as the window only handles events that are sent to it, like for example mouse, keyboard or paint events, and ignoring them would make the program appear hung. What you should do is disable all controls in your frame, this will gray them out and make the user aware of the fact that they can not be interacted with at this moment.

You can also disable the parent frame completely, instead of disabling all controls on it. Look into the wxWindowDisabler class, the constructor has a parameter to indicate a window that can be interacted with, and all other windows of the application will be disabled.

If you later on want to execute a secondary program, then you could use the wxExecute() function to do it.

mghie
That is actually the desired behavior at the moment. The program flow in the first window should really have the results of the interactions in second window before it continues onward.I think what I'm running into here is a design issue. I've fallen victim to the effect Jeff and Joel were talking about in one of their recent podcasts of having to do design in a new framework when I'm still learning it :-).I'll take a look at the wxWindowDisabler. Thanks for the tip.
dagorym
A: 

I was also looking from similar solution and have comeup with this solution, create a frame, disable other windows by doing frame.MakeModal() and to stop execution start and event loop after showing frame, and when frame is closed exit the event loop e.g. I here is sample using wxpython but it should be similar in wxwidgets.

import wx

class ModalFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, style=wx.DEFAULT_FRAME_STYLE|wx.STAY_ON_TOP)

        btn = wx.Button(self, label="Close me")
        btn.Bind(wx.EVT_BUTTON, self.onClose)

    def onClose(self, event):
        self.eventLoop.Exit()
        self.Close()

    def ShowModal(self):
        self.MakeModal()
        self.Show()

        # now to stop execution start a event loop 
        self.eventLoop = wx.EventLoop()
        self.eventLoop.Run()


app = wx.PySimpleApp()
frame = wx.Frame(None, title="Test Modal Frame")
btn = wx.Button(frame, label="Open modal frame")

def onclick(event):
    modalFrame = ModalFrame(frame, "Modal Frame")
    modalFrame.ShowModal()
    print "i will get printed after modal close"

btn.Bind(wx.EVT_BUTTON, onclick)

frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
Anurag Uniyal