WxPython在多个面板

时间:2015-06-30 12:15:50

标签: python 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()

4 个答案:

答案 0 :(得分:1)

问题在于:

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

您正在调用SwitchPanel功能。调用的结果是None(SwitchPanel不返回任何内容),因此它与您执行的操作相同:

    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 :(得分:1)

I actually wrote a tutorial on the topic some time ago. Here's the code:

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()

You might also want to take a look at using one of wxPython's "Book" controls, such as the wx.Notebook.

答案 2 :(得分:1)

You do not require to pass both panel object while creating event for menu item.

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

Get menu item ID by using event.GetId() method to identify which panel to hide and show.

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()

答案 3 :(得分: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()

非常感谢您的想法!