代码之家  ›  专栏  ›  技术社区  ›  dagorym

如何使wxFrame的行为类似于模态wxDialog对象

  •  8
  • dagorym  · 技术社区  · 16 年前

    我正在研究一个 small game 并遇到了以下问题。我有一个主程序窗口,它承载主应用程序(战略部分)。有时,我需要将控制权转移到第二个窗口,以解决部分游戏(战术部分)。在第二个窗口中,我希望第一个窗口中的处理停止并等待在第二个窗口中完成的工作。

    通常情况下,一个模态对话框就可以了,但是我希望新窗口有一些wxDialog无法实现的功能,即底部的状态栏和调整窗口大小/最大化/最小化的能力(这应该是可能的,但不起作用,看这个问题 How to get the minimize and maximize buttons to appear on a wxDialog object

    有人这么做或有什么建议吗?

    3 回复  |  直到 8 年前
        1
  •  4
  •   Nate    10 年前

    我也从类似的解决方案,并想出了这个解决方案,创建一个框架,禁用其他窗口做frame.MakeModal()并在显示frame之后停止执行start和event loop,当frame关闭时,退出事件循环,例如,我这里是使用wxpython的示例,但它在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)
            self.Bind(wx.EVT_CLOSE, self.onClose) # (Allows main window close to work)
    
        def onClose(self, event):
            self.MakeModal(False) # (Re-enables parent window)
            self.eventLoop.Exit()
            self.Destroy() # (Closes window without recursion errors)
    
        def ShowModal(self):
            self.MakeModal(True) # (Explicit call to 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()
    
        2
  •  3
  •   mghie    16 年前

    “停止执行”窗口并没有真正意义,因为窗口只处理发送给它的事件,例如鼠标、键盘或绘画事件,忽略它们会使程序看起来挂起。你应该做的是禁用框架中的所有控件,这将使它们变灰,并使用户意识到此时无法与它们交互。

    类,构造函数有一个参数来指示可以与之交互的窗口,并且应用程序的所有其他窗口都将被禁用。

    如果以后要执行辅助程序,则可以使用 函数来完成它。

        3
  •  3
  •   Nate    10 年前

    import wx
    
    class ChildFrame(wx.Frame):
        ''' ChildFrame launched from MainFrame '''
        def __init__(self, parent, id):
            wx.Frame.__init__(self, parent, -1,
                              title=self.__class__.__name__,
                              size=(300,150))
    
            panel = wx.Panel(self, -1)
            closeButton = wx.Button(panel, label="Close Me")
    
            self.Bind(wx.EVT_BUTTON, self.__onClose, id=closeButton.GetId())
            self.Bind(wx.EVT_CLOSE, self.__onClose) # (Allows frame's title-bar close to work)
    
            self.CenterOnParent()
            self.GetParent().Enable(False)
            self.Show(True)
    
            self.__eventLoop = wx.EventLoop()
            self.__eventLoop.Run()
    
        def __onClose(self, event):
            self.GetParent().Enable(True)
            self.__eventLoop.Exit()
            self.Destroy()
    
    class MainFrame(wx.Frame):
        ''' Launches ChildFrame when button is clicked. '''
        def __init__(self, parent, id):
            wx.Frame.__init__(self, parent, id,
                              title=self.__class__.__name__,
                              size=(400, 300))
    
            panel = wx.Panel(self, -1)
            launchButton = wx.Button(panel, label="launch modal window")
    
            self.Bind(wx.EVT_BUTTON, self.__onClick, id=launchButton.GetId())
    
            self.Centre()
            self.Show(True)
    
        def __onClick(self, event):
            dialog = ChildFrame(self, -1)
            print "I am printed by MainFrame and get printed after ChildFrame is closed"
    
    if __name__ == '__main__':
        app = wx.App()    
        frame = MainFrame(None, -1)
        frame.Show()
        app.MainLoop()
    
        4
  •  0
  •   dex black    5 年前

    不确定这是一个好的答案,但它起作用了。

    bool WinApp1::OnInit()
    {
      if (!wxApp::OnInit())
        return false;
    
      SettingsDialog dialog(m_settingsData);
      dialog.ShowModal();
    
      return false;
    }
    
    SettingsDialog::SettingsDialog(SettingsData& settingsData)
      : m_settingsData(settingsData)
    {
      SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
    
      wxWindow* parent = nullptr;
      Create(parent, wxID_ANY, "Preferences", wxDefaultPosition, wxDefaultSize,
        wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
    

    WinApp1窗口从不被赋予wxFrame,也从不绘制。