8

wxFrame オブジェクトを作成するウィンドウが、wxFrame オブジェクトが終了するまで実行を停止するという点で、wxFrame オブジェクトをモーダル ダイアログ ボックスのように動作させることは可能ですか?

私は小さなゲームに取り組んでおり、次の問題に遭遇しました。メイン アプリケーション (戦略的部分) をホストするメイン プログラム ウィンドウがあります。場合によっては、ゲームの一部 (戦術的な部分) を解決するために、2 番目のウィンドウに制御を移す必要があります。2 番目のウィンドウにいる間に、最初のウィンドウでの処理を停止し、2 番目のウィンドウで行われている作業の完了を待ちます。

通常はモーダル ダイアログでうまくいきますが、新しいウィンドウには、wxDialog では得られないように見える機能、つまり下部のステータス バーと、ウィンドウのサイズ変更/最大化/最小化機能 (この可能なはずですが、機能しません。この質問を参照してください最小化ボタンと最大化ボタンを wxDialog オブジェクトに表示する方法)。

補足として、最終的に別のプログラムに分離されるため、2 番目のウィンドウの機能をプライマリ ウィンドウから完全に分離したままにする必要があります。

誰かがこれをやったことがありますか、何か提案がありますか?

4

4 に答える 4

4

私も同様のソリューションから探していましたが、このソリューションを思いつき、フレームを作成し、frame.MakeModal() を実行して他のウィンドウを無効にし、フレームを表示した後に実行開始とイベントループを停止し、フレームが閉じられたらイベントループを終了します。ここでは 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()
于 2010-04-04T05:26:14.033 に答える
3

ウィンドウは、たとえばマウス、キーボード、またはペイント イベントなど、ウィンドウに送信されたイベントのみを処理し、それらを無視するとプログラムがハングしたように見えるため、ウィンドウの「実行を停止」することは実際には意味がありません。フレーム内のすべてのコントロールを無効にする必要があります。これにより、それらがグレー表示され、現時点では操作できないことがユーザーに認識されます。

親フレームのすべてのコントロールを無効にする代わりに、親フレームを完全に無効にすることもできます。wxWindowDisablerクラスを調べてください。コンストラクターには、対話できるウィンドウを示すパラメーターがあり、アプリケーションの他のすべてのウィンドウが無効になります。

後で二次プログラムを実行したい場合は、wxExecute()関数を使用して実行できます。

于 2009-05-19T17:57:00.140 に答える
3

これを理解するのに厄介な時間がかかりましたが、ここに Anurag の例から生まれた実用的な例があります:

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()
于 2015-01-26T20:51:51.210 に答える