如何使用关闭按钮在 wxPython 笔记本上生成新页面?

How to generate new pages on wxPython notebook with close buttons?

我有以下玩具示例代码,我在 wxPython 笔记本中创建了两个选项卡。有一个添加新页面的按钮,在每个页面中我都想有一个关闭页面的按钮。然而,当点击关闭按钮时,下面的代码没有任何动作。

import wx

class TabPanel(wx.Panel):
    def __init__(self, parent, pageNum):
        self.parent = parent
        self.pageNum = pageNum
        wx.Panel.__init__(self, parent=parent)

        btn = wx.Button(self, label="Close Page " + str(pageNum))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btn, 0, wx.ALL, 10)
        self.SetSizer(sizer)

        btn.Bind(wx.EVT_BUTTON, self.closeTab)

    def closeTab(self,event):
        self.Close()

class DemoFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Notebook", size=(600,400))
        panel = wx.Panel(self)
        self.tab_num = 2

        self.notebook = wx.Notebook(panel)
        tabOne = TabPanel(self.notebook, 1)
        self.notebook.AddPage(tabOne, "Page 1")

        tabTwo = TabPanel(self.notebook, 2)
        self.notebook.AddPage(tabTwo, "Page 2")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)

        btn = wx.Button(panel, label="Add Page")
        btn.Bind(wx.EVT_BUTTON, self.addPage)
        sizer.Add(btn)

        panel.SetSizer(sizer)
        self.Layout()
        self.Show()

    def addPage(self, event):
        self.tab_num += 1
        new_tab = TabPanel(self.notebook, self.tab_num)
        self.notebook.AddPage(new_tab, "Page %s" % self.tab_num)

if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()

该代码生成如下 window:

问题

关闭按钮没有执行任何操作。

问题

我应该如何更改我的代码才能让关闭按钮关闭它所在的相应页面?

不确定是否有更好的解决方案,但添加一个全局变量 tabs 这是一个包含实际选项卡的列表,并对 closeTab 函数进行一些更改即可完成工作。

关闭选项卡的方法是使用 Notebook 对象中的 RemovePage 函数。

import wx
tabs = [1,2]

class TabPanel(wx.Panel):
    def __init__(self, parent, pageNum):
        self.parent = parent
        self.pageNum = pageNum
        wx.Panel.__init__(self, parent=parent)

        btn = wx.Button(self, label="Close Page " + str(pageNum))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btn, 0, wx.ALL, 10)
        self.SetSizer(sizer)

        btn.Bind(wx.EVT_BUTTON, self.closeTab)

    def closeTab(self,event):
        notebook = self.parent
        notebook.RemovePage(tabs.index(self.pageNum))
        tabs.remove(self.pageNum)

class DemoFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Notebook", size=(600,400))
        panel = wx.Panel(self)
        self.tab_num = len(tabs)

        self.notebook = wx.Notebook(panel)
        tabOne = TabPanel(self.notebook, 1)
        self.notebook.AddPage(tabOne, "Page 1")

        tabTwo = TabPanel(self.notebook, 2)
        self.notebook.AddPage(tabTwo, "Page 2")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)

        btn = wx.Button(panel, label="Add Page")
        btn.Bind(wx.EVT_BUTTON, self.addPage)
        sizer.Add(btn)

        panel.SetSizer(sizer)
        self.Layout()
        self.Show()

    def addPage(self, event):
        self.tab_num += 1
        new_tab = TabPanel(self.notebook, self.tab_num)
        self.notebook.AddPage(new_tab, "Page %s" % self.tab_num)
        tabs.append(self.tab_num)
        print tabs

if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()

如果您使用 wx.NotebookGetSelection() 方法,可能会更容易。该方法returns 当前选中页面的索引。之后,您可以直接删除所选页面。

带注释的代码 (####):

import wx

class TabPanel(wx.Panel):
    def __init__(self, parent, pageNum):
        self.parent = parent
        self.pageNum = pageNum
        wx.Panel.__init__(self, parent=parent)

        btn = wx.Button(self, label="Close Page " + str(pageNum))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(btn, 0, wx.ALL, 10)
        self.SetSizer(sizer)

        btn.Bind(wx.EVT_BUTTON, self.closeTab)

    def closeTab(self,event):
        #### Just one line and no extra variable to remove the selected page
        self.parent.RemovePage(self.parent.GetSelection())

class DemoFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Notebook", size=(600,400))
        panel = wx.Panel(self)
        self.tab_num = 2

        self.notebook = wx.Notebook(panel)
        tabOne = TabPanel(self.notebook, 1)
        self.notebook.AddPage(tabOne, "Page 1")

        tabTwo = TabPanel(self.notebook, 2)
        self.notebook.AddPage(tabTwo, "Page 2")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)

        btn = wx.Button(panel, label="Add Page")
        btn.Bind(wx.EVT_BUTTON, self.addPage)
        sizer.Add(btn)

        panel.SetSizer(sizer)
        self.Layout()
        self.Show()

    def addPage(self, event):
        self.tab_num += 1
        new_tab = TabPanel(self.notebook, self.tab_num)
        self.notebook.AddPage(new_tab, "Page %s" % self.tab_num)

if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()