1

4 ページ (またはそれ以上) の wxPython を使用して GUI フローを作成しています。私がアプローチした方法は、各クラスが独自の静的(背景)および動的画像/コンテンツを定義する4つ(またはそれ以上)のクラスを作成することです。私のアプリケーションでは、必要なインスタンス クラスをプログラムで作成し、そのページでイベントをキャプチャします。トリガーされたイベントに基づいて、登録されたハンドラーは現在のクラスを破棄し、他のクラス (ページ) に切り替えます。したがって、私のコードは実際に X クラスを作成し、各クラスには背景/前景のコンテンツ/画像を設定する独自のメソッドがあります。

def OnEraseBackground(self, evt):
    dc = evt.GetDC()

    if not dc:
        dc = wx.ClientDC(self)
        rect = self.GetUpdateRegion().GetBox()
        dc.SetClippingRect(rect)
    dc.Clear()
    bmp = wx.Bitmap(self.image)
    dc.DrawBitmap(bmp, 0, 0)

def buttonClick(self, evt):
    parent = self.frame
    self.Destroy()
    DispatchState(parent, "admin1.png", 1)

問題は、2 ページ目が画面にまったく表示されないことです。

以下は私の完全なコードです。アプリケーション フレームのパネルに画面を作成する 2 つのクラス (MainPanel、SecondPanel) を作成したことに注意してください。その後、イベントを待ちます。目的のイベントを取得したら、現在のクラスを削除し、新しいクラスのインスタンスを作成します。

import wx

########################################################################
class SecondPanel(wx.Panel):
    def __init__(self,parent, image, state):
        wx.Panel.__init__(self, parent=parent)
    self.state = state
    self.image = image
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.frame = parent
        sizer = wx.BoxSizer(wx.VERTICAL)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
    panel=wx.Panel(self, -1)

    self.buttonOne=wx.Image("image1.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
    self.button=wx.BitmapButton(self, -1, self.buttonOne, pos=(100,50))
    self.button.Bind(wx.EVT_LEFT_DCLICK, self.buttonClick)
        sizer.Add(self.button, 0, wx.ALL, 5)
        hSizer.Add((1,1), 1, wx.EXPAND)
        hSizer.Add(sizer, 0, wx.TOP, 100)
        hSizer.Add((1,1), 0, wx.ALL, 75)
        self.SetSizer(hSizer)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

    def buttonClick(self, evt):
    parent = self.frame
    self.Destroy()
    DispatchState(parent, "admin0.png", 0)

    def OnEraseBackground(self, evt):
    dc = evt.GetDC()

    if not dc:
        dc = wx.ClientDC(self)
        rect = self.GetUpdateRegion().GetBox()
        dc.SetClippingRect(rect)
    dc.Clear()
    bmp = wx.Bitmap(self.image)
    dc.DrawBitmap(bmp, 0, 0)

class MainPanel(wx.Panel):
    def __init__(self,parent, image, state):
        wx.Panel.__init__(self, parent=parent)
    self.state = state
    self.image = image
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.frame = parent
        sizer = wx.BoxSizer(wx.VERTICAL)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
    panel=wx.Panel(self, -1)
    self.buttonOne=wx.Image("image0.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
    self.button=wx.BitmapButton(self, -1, self.buttonOne, pos=(100,50))
    self.button.Bind(wx.EVT_LEFT_DCLICK, self.buttonClick)
        sizer.Add(self.button, 0, wx.ALL, 5)
        hSizer.Add((1,1), 1, wx.EXPAND)
        hSizer.Add(sizer, 0, wx.TOP, 100)
        hSizer.Add((1,1), 0, wx.ALL, 75)
        self.SetSizer(hSizer)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

    def buttonClick(self, evt):
    parent = self.frame
    self.Destroy()
    DispatchState(parent, "admin1.png", 1)

    def OnEraseBackground(self, evt):
    dc = evt.GetDC()

    if not dc:
        dc = wx.ClientDC(self)
        rect = self.GetUpdateRegion().GetBox()
        dc.SetClippingRect(rect)
    dc.Clear()
    bmp = wx.Bitmap(self.image)
    dc.DrawBitmap(bmp, 0, 0)


 class Main(wx.App):
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)
        self.frame = wx.Frame(None, size=(800, 480))
        self.state = 0
        self.image = 'admin0.png'

def DispatchState(frame, image, state):
        if state == 0 :
            print image
            print state
            MainPanel(frame, image, state)
        if state == 1 :
            print image
            print state
            SecondPanel(frame, image, state)
        frame.Show()


if __name__ == "__main__":
    app = Main()
    DispatchState(app.frame,app.image, app.state)
    app.MainLoop()

このアプローチを選択した理由は、任意の画面/ページに切り替えることができるように、ある状態から別の状態に簡単に切り替えることができるためです。明日、さらに多くのページを動的に追加/削除する必要がある場合、簡単に実行できます。ページ (クラス) を作成し、その状態を DispatchState() グローバル メソッドに追加する必要があります。

しかし、私にとって現在、2番目の画面はまったくレンダリングされません。また、私のアプローチについてコメントしてください - これを達成するためのより良い方法はありますか?

4

1 に答える 1

1

いくつかの解決策。

パネルのサイズをフレームのサイズに変更するサイザーMyFrameを追加するクラスを作成する必要があります。

よりオブジェクト指向にするために追加DispatchStateします。現在、 PanelはFrame関数を呼び出し、 Frameはパネルを作成/破棄します。ChangePanelMyFrameChangePanel

SecondPanelMainPanelは非常に似ているため、1 つのMyPanelクラスを作成しました。エラーを削除する作業を減らすためです :) - DRYルールを参照してください: Don't Repeat Yourself

(他のユーザーもこのコードを実行できるように、ビットマップを添付します)

( image0.bmp 、 image1.bmp の代わりに ball1.png 、 ball2.png を使用します)

import wx

#######################################################################

class MyPanel(wx.Panel):

    def __init__(self, parent, state, button_image, background_image):
        wx.Panel.__init__(self, parent=parent)

        print "(debug) MyPanel.__init__: state:", state

        self.parent = parent
        self.state  = state

        self.button_image = button_image
        self.background_image = background_image


        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)

        vsizer = wx.BoxSizer(wx.VERTICAL)
        hSizer = wx.BoxSizer(wx.HORIZONTAL)

        #self.buttonOne=wx.Image("image1.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
        self.buttonImage = wx.Image(button_image, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        self.button = wx.BitmapButton(self, -1, self.buttonImage, pos=(100,50))

        self.button.Bind(wx.EVT_LEFT_DCLICK, self.buttonClick)

        self.backgroundImage = wx.Bitmap(self.background_image)

        vsizer.Add(self.button, 0, wx.ALL, 5)

        hSizer.Add((1,1), 1, wx.EXPAND)
        hSizer.Add(vsizer, 0, wx.TOP, 100)
        hSizer.Add((1,1), 0, wx.ALL, 75)

        self.SetSizer(hSizer)

        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

    def buttonClick(self, evt):
        print "(debug) MyPanel.buttonClick"
        self.parent.ChangePanel()

    def OnEraseBackground(self, evt):
        dc = evt.GetDC()

        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        dc.Clear()
        dc.DrawBitmap(self.backgroundImage, 0, 0)

#######################################################################

class MyFrame(wx.Frame):

    def __init__(self, size=(800,480)):
        wx.Frame.__init__(self, None, size=size)

        self.state = None
        self.panel = None

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)

        self.Show() # Show is used to show/hide window not to update content

        self.ChangePanel()

    #--------------------------

    def ChangePanel(self):

        print "(debug) MyFrame.ChangePanel: state:", self.state

        if self.state is None or self.state == 1:
            # change state
            self.state = 0 

            # destroy old panel
            if self.panel:
                self.panel.Destroy()

            # create new panel
            self.panel = MyPanel(self, self.state, "ball1.png", "admin0.png")

            # add to sizer
            self.sizer.Add(self.panel, 1, wx.EXPAND)
        elif self.state == 0 :
            # change state
            self.state = 1 

            # destroy old panel
            if self.panel:
                self.panel.Destroy()

            # create new panel
            self.panel = MyPanel(self, self.state, "ball2.png", "admin1.png")

            # add to sizer
            self.sizer.Add(self.panel, 1, wx.EXPAND)
        else:
            print "unkown state:", self.state

        self.Layout() # refresh window content

#######################################################################

class Application(wx.App):

    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)   
        self.frame = MyFrame((800, 480))

    def run(self):
        self.MainLoop()

#######################################################################

if __name__ == "__main__":
    Application().run()

ball1.png ball1.pngball2.pngball2.png

admin0.png admin0.png

admin1.png admin1.png

于 2013-11-11T19:00:02.170 に答える