2014-02-20 30 views
2

我正在研究一个相当大的GUI项目,因此使用wxpython来构建它。我有一个框架,多个框架与他们自己的功能和一个主要文件,导入gui组件以及其他外部功能。我决定保持gui/wxpython代码不同以更好地模块化代码。wxpython - 一个框架,多个面板,模块化代码

我的主要问题是如何执行单独的面板中的功能,以及如何使他们从我的主要python文件工作。

下面是我的wxPython代码示例:

import wx 

class MainFrame (wx.Frame): 

    def __init__(self, parent): 
     wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

     bSizer1 = wx.BoxSizer(wx.VERTICAL) 

     self.SetSizer(bSizer1) 
     self.Layout() 

     self.panelOne = panel_one(self) 
     self.panelTwo = panel_two(self) 

     self.panelTwo.Hide() 


     self.Centre(wx.BOTH) 

    def __del__(self): 
     pass 


class panel_one (wx.Panel): 

    def __init__(self, parent): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.TAB_TRAVERSAL) 

     bSizer5 = wx.BoxSizer(wx.VERTICAL) 

     self.m_button2 = wx.Button(self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0) 
     bSizer5.Add(self.m_button2, 0, wx.ALL, 5) 

     self.SetSizer(bSizer5) 
     self.Layout() 

     # Connect Events 
     self.m_button2.Bind(wx.EVT_BUTTON, self.changeIntroPanel) 

    def __del__(self): 
     pass 


    # Virtual event handlers, overide them in your derived class 
    def changeIntroPanel(self, event): 
     event.Skip() 



class panel_two (wx.Panel): 


    def __init__(self, parent): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.TAB_TRAVERSAL) 

    ... some code in here ... 

    def __del__(self): 
    pass 

因此,这些都是我的GUI组件。然后,在我的主文件,我导入并运行GUI:

import gui 

class MainApp(gui.MainFrame): 
    def __init__(self, parent): 
     gui.MainFrame.__init__(self, parent) 

     self.panelOne = Panel1(self) 
     self.panelTwo = Panel2(self) 
     self.panelTwo.Hide() 

class Panel1(gui.panel_one): 
    def __init__(self, parent): 
     gui.panel_one.__init__(self, parent) 

    def changeIntroPanel(self, event): 
      if self.panelOne.IsShown(): 
       self.SetTitle("Panel Two Showing") 
       self.PanelOne.Hide() 
       self.PanelTwo.Show() 
      else: 
       self.SetTitle("Panel One Showing") 
       self.PanelOne.Show() 
       self.PanelTwo.Hide() 
      self.Layout() 


class Panel2(gui.panel_two): 
    def __init__(self, parent): 
     gui.panel_two.__init__(self, parent) 

def main(): 
    app = wx.App() 
    window = MainApp(None) 
    window.Show(True) 
    app.MainLoop() 

if __name__ == '__main__': 
    main() 

可以这样说,这个想法是,我要尽我所有的实现在我的主文件。我将如何去定义我首先在panel_one中定义的changeIntroPanel函数的功能?目前,这个想法是隐藏panelOne并显示panelTwo。

我以前做过类似的事情,但只有一帧。在这种情况下,因为所有的函数都是在MainFrame类中开始的,所以它是微不足道的。在这种情况下,我发布的代码将完美工作。

任何帮助表示赞赏。谢谢。

+0

覆盖派生类中的changeIntroPanel。您可以定义类MainPanelOne(gui.panel_one),就像您的“MainApp” –

+0

谢谢您的输入。正如你所说,我这样做了。我的想法是创建两个面板,并在main()中调用window = MainApp(None)时传递它们。问题是,虽然正在创建p1和p2,但我得到以下异常:无法在没有父项的情况下创建wxWindowMac。看到我可以创建没有父母的框架,谁不是面板? – intl

+1

如何: 窗口= MainApp(无) P1 = Panel1的(窗口) P2 =是Panel2(窗口) window.Show() –

回答

6

def OnInit(self, parent):用于wx.App,您需要使用def _ _init_ _(self, parent)

关于__init__请检查:Using inheritance in python

关于__init__OnInit之间的差异请this link

编辑:

gui.py

import wx 

class MainFrame (wx.Frame): 
    def __init__(self, parent): 
     wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 
     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 
     bSizer1 = wx.BoxSizer(wx.VERTICAL) 
     self.SetSizer(bSizer1) 
     self.Layout() 

     # self.panelOne = panel_one(self) 
     # self.panelTwo = panel_two(self) 
     # self.panelTwo.Hide() 
     self.Centre(wx.BOTH) 
    def __del__(self): 
     pass 

class panel_one (wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.TAB_TRAVERSAL) 
     bSizer5 = wx.BoxSizer(wx.VERTICAL) 
     self.m_button2 = wx.Button(self, wx.ID_ANY, u"panel 1 button", wx.DefaultPosition, wx.DefaultSize, 0) 
     bSizer5.Add(self.m_button2, 0, wx.ALL, 5) 
     self.SetSizer(bSizer5) 
     self.Layout() 
     # Connect Events 
     self.m_button2.Bind(wx.EVT_BUTTON, self.changeIntroPanel) 
    def __del__(self): 
     pass 
    # Virtual event handlers, overide them in your derived class 
    def changeIntroPanel(self, event): 
     event.Skip() 

class panel_two (wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size(800,600), style = wx.TAB_TRAVERSAL) 
     bSizer5 = wx.BoxSizer(wx.VERTICAL) 
     self.m_button2 = wx.Button(self, wx.ID_ANY, u"panel 2 button ", wx.DefaultPosition, wx.DefaultSize, 0) 
     bSizer5.Add(self.m_button2, 0, wx.ALL, 5) 
     self.SetSizer(bSizer5) 
     self.Layout() 
     # Connect Events 
     self.m_button2.Bind(wx.EVT_BUTTON, self.changeIntroPanel) 

    def __del__(self): 
     pass 
     # Virtual event handlers, overide them in your derived class 
    def changeIntroPanel(self, event): 
     event.Skip() 

mainapp.py

import wx 
import gui 

class MainApp(gui.MainFrame): 
    def __init__(self, parent): 
     gui.MainFrame.__init__(self, parent) 

     self.panelOne = Panel1(self) 
     self.panelTwo = Panel2(self) 
     self.panelTwo.Hide() 

class Panel1(gui.panel_one): 
    def __init__(self, parent): 
     gui.panel_one.__init__(self, parent) 
     self.parent = parent 

    def changeIntroPanel(self, event): 
     if self.IsShown(): 
      self.parent.SetTitle("Panel Two Showing") 
      self.Hide() 
      self.parent.panelTwo.Show() 


class Panel2(gui.panel_two): 
    def __init__(self, parent): 
     gui.panel_two.__init__(self, parent) 
     self.parent = parent 

    def changeIntroPanel(self, event): 
     if self.IsShown(): 
      self.parent.SetTitle("Panel One Showing") 
      self.parent.panelOne.Show() 
      self.Hide() 

def main(): 
    app = wx.App() 
    window = MainApp(None) 
    window.Show(True) 
    app.MainLoop() 

if __name__ == '__main__': 
    main() 
+0

谢谢。这将面板添加到框架(尽管我对__init__有点困惑,而不是OnInit)。但是,def changeIntroPanel仍然不起作用。问题是它需要引用MainFrame类,但它不能。 – intl

+0

更新:我可以通过在我的MainAPP __init__中绑定函数来解决问题,然后将def changeIntroPanel引入MainApp本身。这是唯一的方法,还是有更好的方法来保持Panel1中的功能并使用它? – intl

+1

@intl类明白你的目的,请检查更新答案。 –