2015-06-30 144 views
0

我是wxpython的新手,正在開發我的第一個應用程序。我知道這個話題有很多,但我沒有看到對我的問題特別有幫助。我想有更多的兩個面板,並像這樣開關多個面板之間的WxPython切換

def switch(self, newactpanel) 
    self.actpanel.Hide() 
    self.actpanel=newactpanel 
    self.actpanel.Show() 

到目前爲止這是行不通的。該應用程序啓動,按鈕出現,但兩個面板視圖一次出現,或只有一個出現,我不能切換。如何構建一個def來切換更多面板?

非常感謝您的回答。

這裏是我的代碼:

import wx 

ID_EXIT=200 
ID_ADDKEYWORDS = 301 
ID_WRITEINTERP = 302 
h_frame = 750 
w_frame = 325 

class SubPanel(wx.Panel): 
    """""" 
    def __init__(self, parent): 
     """Constructor""" 
     wx.Panel.__init__(self, parent=parent) 

class AddKeyWordsPanel(wx.Panel): 
    def __init__(self, parent,size): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = size) 
     panel1 = SubPanel(self) 

     some_val = "Add KeyWords" 
     something = wx.TextCtrl(panel1, -1,some_val, size=(h_frame,24), style=wx.TE_READONLY|wx.SIMPLE_BORDER|wx.TE_CENTRE) 
     box = wx.BoxSizer(wx.VERTICAL) 
     box.Add(panel1, 1, wx.EXPAND) 

     self.SetAutoLayout(True) 
     self.SetSizer(box) 


class WritePanel(wx.Panel): 
    def __init__(self, parent,size): 
     wx.Panel.__init__ (self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = size) 
     panel1 = SubPanel(self) 
     panel2 = SubPanel(self) 
     panel3 = SubPanel(self) 

     keys_val = self.GetKeyNames() 
     keys = wx.TextCtrl(panel1, -1,keys_val, size=(h_frame,24), style=wx.TE_READONLY|wx.SIMPLE_BORDER|wx.TE_CENTRE) 
     font = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL) 
     keys.SetFont(font) 

     keywords1_val = self.GetKeyWords(keys_val) 
     keywords1 = wx.TextCtrl(panel2, -1,keywords1_val, size=(h_frame,100), style=wx.TE_READONLY|wx.BORDER_NONE) 

     txtentry_val = "" 
     txtentry = wx.TextCtrl(panel3, -1, txtentry_val, size=(h_frame, 200)) 
     txtentry.SetBackgroundColour("WHITE") 
     txtentry.SetInsertionPoint(0) 

     box = wx.BoxSizer(wx.VERTICAL) 
     box.Add(panel1, 3, wx.EXPAND) 
     box.Add(panel2, 2, wx.EXPAND) 
     box.Add(panel3, 1, wx.EXPAND) 

     self.SetAutoLayout(True) 
     self.SetSizer(box) 



    def GetKeyNames(self): 
     return "Blabla1" 

    def GetKeyWords(self,keys): 
     return "Blabla2" 


class MainFrame(wx.Frame): 
    def __init__(self, parent, ID, title): 
     wx.Frame.__init__(self, parent, ID, title, size=(h_frame, w_frame)) 

     self.CreateStatusBar() 

     menu= wx.Menu() 
     menu.Append(ID_ADDKEYWORDS,"&Add KeyWords"," Add Keywords") 
     menu.Append(ID_WRITEINTERP,"&Write Interpretations"," Write Interpretations") 
     menu.Append(ID_EXIT,"E&xit"," Terminate the program") 
     menuBar = wx.MenuBar() 
     menuBar.Append(menu,"&Menu") 
     self.SetMenuBar(menuBar) 

     self.wrtpnl = WritePanel(self,(h_frame,w_frame)) 
     self.addkeywpnl = AddKeyWordsPanel(self,(h_frame,w_frame)) 

     self.panel = self.wrtpnl 
     self.panel.Layout() 

     wx.EVT_MENU(self, ID_ADDKEYWORDS, self.SwitchPanel(self.addkeywpnl)) 
     wx.EVT_MENU(self, ID_WRITEINTERP, self.SwitchPanel(self.wrtpnl)) 
     wx.EVT_MENU(self, ID_EXIT, self.OnExit) 

     self.doiexit = wx.MessageDialog(self, " Exit - R U Sure? \n","GOING away ...", wx.YES_NO) 




    def SwitchPanel(self,show_pnl): 
     self.panel.Hide() 
     self.panel = show_pnl 
     self.panel.Layout() 
     self.panel.Show() 
     self.Layout() 

    def OnExit(self,e): 
     igot = self.doiexit.ShowModal() 
     if igot == wx.ID_YES: 
      self.Close(True) 

app = None 
app = wx.App() 
frame = MainFrame(None, -1, "KeyWordTool") 
frame.Show() 
app.MainLoop() 

回答

0

好吧,我想我的三個建議組合解決了這個問題。這不完全是我想要的,但非常接近。它的工作原理和這種方式,我不需要爲每個按鈕/面板有一個特定的開關功能。我的解決方案是這樣的:

self.wrtpnl = WritePanel(self,(h_frame,w_frame)) 
    self.addkeywpnl = AddKeyWordsPanel(self,(h_frame,w_frame)) 

    self.pnldic = {ID_ADDKEYWORDS:self.addkeywpnl, ID_WRITEINTERP:self.wrtpnl} 

    wx.EVT_MENU(self, ID_ADDKEYWORDS, self.SwitchPanel) 
    wx.EVT_MENU(self, ID_WRITEINTERP, self.SwitchPanel) 
    wx.EVT_MENU(self, ID_EXIT, self.OnExit) 


def SwitchPanel(self,event): 
    self.panel.Hide() 
    self.panel = self.pnldic[event.GetId()] 
    self.panel.Layout() 
    self.panel.Show() 
    self.Layout() 

非常感謝這些想法!

1

麻煩的是,上線:

wx.EVT_MENU(self, ID_ADDKEYWORDS, self.SwitchPanel(self.addkeywpnl)) 
    wx.EVT_MENU(self, ID_WRITEINTERP, self.SwitchPanel(self.wrtpnl)) 

您呼叫的功能已經配電。調用的結果是無(配電不返回任何東西),所以,如果你做同樣的事情:

wx.EVT_MENU(self, ID_ADDKEYWORDS, None) 
    wx.EVT_MENU(self, ID_WRITEINTERP, None) 

可能最理解的解決方案是:

wx.EVT_MENU(self, ID_ADDKEYWORDS, self.SwitchPanel1) 
    wx.EVT_MENU(self, ID_WRITEINTERP, self.SwitchPanel2) 
    # [...] 

def SwitchPanel1(self, evt): 
    evt.Skip() 
    self.SwitchPanel(self.addkeywpnl) 

def SwitchPanel2(self, evt): 
    evt.Skip() 
    self.SwitchPanel(self.wrtpnl) 
1

其實我寫的前段時間有關該主題的tutorial。下面的代碼:

import wx 
import wx.grid as gridlib 

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

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

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

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

     grid = gridlib.Grid(self) 
     grid.CreateGrid(25,12) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(grid, 0, wx.EXPAND) 
     self.SetSizer(sizer) 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, 
          "Panel Switcher Tutorial") 

     self.panel_one = PanelOne(self) 
     self.panel_two = PanelTwo(self) 
     self.panel_two.Hide() 

     self.sizer = wx.BoxSizer(wx.VERTICAL) 
     self.sizer.Add(self.panel_one, 1, wx.EXPAND) 
     self.sizer.Add(self.panel_two, 1, wx.EXPAND) 
     self.SetSizer(self.sizer) 


     menubar = wx.MenuBar() 
     fileMenu = wx.Menu() 
     switch_panels_menu_item = fileMenu.Append(wx.ID_ANY, 
                "Switch Panels", 
                "Some text") 
     self.Bind(wx.EVT_MENU, self.onSwitchPanels, 
        switch_panels_menu_item) 
     menubar.Append(fileMenu, '&File') 
     self.SetMenuBar(menubar) 

    #---------------------------------------------------------------------- 
    def onSwitchPanels(self, event): 
     """""" 
     if self.panel_one.IsShown(): 
      self.SetTitle("Panel Two Showing") 
      self.panel_one.Hide() 
      self.panel_two.Show() 
     else: 
      self.SetTitle("Panel One Showing") 
      self.panel_one.Show() 
      self.panel_two.Hide() 
     self.Layout() 


# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 

你可能也想看看使用wxPython中的「書」控制一個,如wx.Notebook

+0

嗨,感謝您的回覆。我知道你的教程,但是我有這個方法的問題。可以說我有20個面板,並希望在它們之間切換。我是否需要編寫一個if self.panel_one,elif self.panel_two ... elif self.panel_twenty?如果可能的話,我正在尋找一種動態,乾淨的好方法。 – Stefan

+1

我只會使用面板字典。然後,當您想要切換時,只需將該鍵傳遞給該面板並切換到該面板即可。或者只是實例化新面板並銷燬舊面板,這樣就不會將所有面板始終放在內存中。 –

1

您不需要在爲菜單項創建事件時傳遞兩個面板對象。

wx.EVT_MENU(self, ID_ADDKEYWORDS, self.SwitchPanel) 
wx.EVT_MENU(self, ID_WRITEINTERP, self.SwitchPanel) 

通過使用event.GetId()方法來確定要隱藏和顯示哪個面板來獲取菜單項ID。

def SwitchPanel(self,event): 
    self.panel.Hide() 
    if event.GetId() == ID_ADDKEYWORDS: 
     self.panel = self.addkeywpnl 
    elif event.GetId() == ID_WRITEINTERP: 
     self.panel = self.wrtpnl 
    self.panel.Layout() 
    self.panel.Show() 
    self.Layout() 
+0

嗨,謝謝你的回覆。我已經看到了這種方法,但是如果我需要在20個面板之間切換,該怎麼辦?如果我寫了20個病例,elif?如果存在這樣的話,我實際上正在尋找更清潔的解決方案。 – Stefan

+1

@Stefan您可以創建一個面板字典,並用ID鍵入。那麼你可以在字典中查詢面板而不是一系列if語句 – GP89

+0

@ GP89:直到現在我還沒有看到你的評論。但字典正是我所做的,它的工作原理。好想法。謝謝! – Stefan