1

wxPython (他のモジュールなし) でゲームを作成したいのですが、ゲームの開始前にポップアップ画面にいくつかの値を入力できるようにしたいと考えています。その後、ゲームはキャンバス上に描画され、キャンバス上に描画されます。メインゲームにバインドされているパネル。

私はすべてのファンシーなものでゲーム画面を作成しました (ソロで動作します) 入力画面を作成しましたが、それらをリンクすることはできません。

ダイアログボックスを開き、それを閉じると別のダイアログボックスを開いてからゲームを開くようにゲームを開始するにはどうすればよいですか?

次のことを試しましたが、キャンバスが開きません。

# makes a game by showing 2 dialogs
# after dialogs have been answered, starts the game by drawing the canvas.

# imports  
import wx
import Speelveld3

# globals
SCRWIDTH = 950
SCRHEIGHT = 700

# dialogbox class
class MyDialog1(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent)

        self.username = wx.TextCtrl(self)
        self.okButton = wx.Button(self, wx.ID_OK, "OK")

class MyDialog2(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent)

        self.canvasWidth = wx.TextCtrl(self)
        self.okButton = wx.Button(self, wx.ID_OK, "OK")

# main class
class Game(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, title='My game', size=(SCRWIDTH, SCRHEIGHT))
        self.username = ""
        self.canvasWidth = 10
        # hide the frame for now
        self.Hide()

    def OnInit(self):
        #Make your dialogs
        dlg1 = MyDialog1(self)
        #if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
        if dlg1.ShowModal() == wx.ID_OK:
            #get the username from the dialog
            self.username = dlg1.username.GetValue()
        #clean up the dialog (AFTER you get the username)
        dlg1.Destroy()

        dlg2 = MyDialog2(self)
        #if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
        if dlg2.ShowModal() == wx.ID_OK:
            #get the username from the dialog
            self.canvasWidth = dlg2.canvasWidth.GetValue()
        #clean up the dialog (AFTER you get the username)
        dlg2.Destroy()



        # Now that you have your settings, Make the gameboard
        # THIS PART IS STILL BROKEN!
        # I can paste the whole board class (structure of it is taken from the tetris tutorial)
        # but that seems a bit much tbh...
        self.gameBoard = Board.Board(self)
        self.gameBoard = SetFocus()
        self.gameBoard.start()

        self.Centre()
        self.Show(True) #show the frame





if __name__ == '__main__':
# how can I start the game here?
    app = wx.App()
    frame = Game()
    board = Speelveld3.Speelveld(frame)
    board.start()
    frame.Show()
    app.MainLoop()
4

2 に答える 2

1

あなたは を二重投稿しましたが、あなたのサンプル コードに 1 つもwx.Dialog含まれていないことから、あなたはまだチュートリアルを見ていないことがわかりますが、疑いの余地はありません。

まず、ダイアログから情報を返したい場合、最も簡単な方法はカスタム ダイアログを定義することです。から継承する新しいクラスを定義しwx.Dialog、通常のパネルやフレームと同じように設定します。この2つが必要になりそうです。それらは次のようになります。

class MyDialog1(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent)

        self.username = wx.TextCtrl(self) #this is where users will enter their username

        self.okButton = wx.Button(self, wx.ID_OK, "OK") #Note that I'm using wx.ID_OK. This is important

さて、あなたが望むロジックのために。実際に目にする wxPython のほとんどすべてのオブジェクトには関数Show()Hide()(API here ) があります。ダイアログが終了するまでフレームを表示したくないので、__init__()で を呼び出しますHide()。また、変数 を初期化していますusername。これは、ダイアログからのデータを保存する場所です。

class Game(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(SCRWIDTH, SCRHEIGHT))
        self.username = ""

        self.Hide() #don't show the frame just yet
        #self.Hide() is the exact same as self.Show(False)

さて、あなたのダイアログのために。Mike Driscoll が提案したように、キャンバスを作成する前にダイアログを呼び出します。wx.Dialogsを使用して起動されShowModal()ます。の ID をself.okButton定数に設定することによりwx.ID_OK、wxPython は、ボタンがクリックされた後にダイアログを閉じる必要があることを認識します。にも注意する必要がありますwx.ID_CANCEL

def OnInit(self):
    #Make your dialogs
    dlg1 = MyDialog1(self)
    if dlg1.ShowModal() == wx.ID_OK:
        #if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
        self.username = dlg1.username.GetValue() #get the username from the dialog
    dlg1.Destroy() #clean up the dialog (AFTER you get the username)

    #do this again for your second dialog

    #Now that you have your settings, Make the gameboard
    self.gameBoard = Board.Board(self)
    self.gameBoard = SetFocus()
    self.gameBoard.start()

    self.Centre()
    self.Show(True) #show the frame
于 2012-06-28T01:48:17.180 に答える
1

OnInit では、Board インスタンスを作成する前に、ダイアログを呼び出してモーダルに表示するだけです。その後、正しく動作するはずです。

編集 (6-28-12):ここにいくつかのコードがあります:

import wx

########################################################################
class MyDlg(wx.Dialog):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Dialog.__init__(self, None, title="I'm a dialog!")

        lbl = wx.StaticText(self, label="Hi from the panel's init!")
        btn = wx.Button(self, id=wx.ID_OK, label="Close me")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(lbl, 0, wx.ALL, 5)
        sizer.Add(btn, 0, wx.ALL, 5)
        self.SetSizer(sizer)


########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        # show a custom dialog
        dlg = MyDlg()
        dlg.ShowModal()
        dlg.Destroy()

        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, evt):
        pdc = wx.PaintDC(self)
        try:
            dc = wx.GCDC(pdc)
        except:
            dc = pdc
        rect = wx.Rect(0,0, 100, 100)
        for RGB, pos in [((178,  34,  34), ( 50,  90)),
                         (( 35, 142,  35), (110, 150)),
                         ((  0,   0, 139), (170,  90))
                         ]:
            r, g, b = RGB
            penclr   = wx.Colour(r, g, b, wx.ALPHA_OPAQUE)
            brushclr = wx.Colour(r, g, b, 128)   # half transparent
            dc.SetPen(wx.Pen(penclr))
            dc.SetBrush(wx.Brush(brushclr))
            rect.SetPosition(pos)
            dc.DrawRoundedRectangleRect(rect, 8)

########################################################################
class MyFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example frame")

        # show a MessageDialog
        style = wx.OK|wx.ICON_INFORMATION
        dlg = wx.MessageDialog(parent=None, 
                               message="Hello from the frame's init", 
                               caption="Information", style=style)
        dlg.ShowModal()
        dlg.Destroy()

        # create panel
        panel = MyPanel(self)

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    frame.Show()
    app.MainLoop()
于 2012-06-27T20:43:54.677 に答える