Search code examples
tabsevent-handlingwxpython

wxpython: How to make a tab active once it is opened via an event handler?


I am making this GUI tool using wxpython. For that I have a menu and a few menu-items. Now, when I click on a particular menu-item, I have written the code for the event that handles the menu-item click. It creates a new sheet(panel, and a listctrl inside it) and adds the page to the already-created wx.Notebook object. Now, when I click on one menu-item after another, I want the tabs opened successively to be active (that is, the one that is shown to the user at that moment), whereas what actually happens is that the first tab opened is the one that stays active. May I please know how this can be achieved?

Here is the code for the event-handlers:

# code for one menu-item click - 
def displayApps(self, event):
    self.appsTab = TabPanel(self.notebook)
    self.notebook.AddPage(self.appsTab, "List of applications running on each node") 
    self.apps = wx.ListBox(self.appsTab, 12, (10, 40),(450,150), self.appslist, wx.LB_SINGLE) #creating the listbox inside the panel in the tab

# code for another menu-item click - 
def displayFreeNodes(self, event):
    #displays the list of free nodes in panel1
    self.freenodesTab = TabPanel(self.notebook)
    self.notebook.AddPage(self.freenodesTab, "List of free nodes in the cluster")
    self.freenodes = wx.ListBox(self.freenodesTab, 13, (10,40),(200,130), self.freenodeslist, wx.LB_SINGLE)
    #self.boxsizer1.Add(self.freenodes, 1)

Solution

  • Mike Driscoll, who is actually quite active here on SO, has written a blog post that shows you how to change pages in a wx.Notebook. It looks like you want to use the wx.Notebook.SetSelection() method. Unfortunately, the documentation for this method does not make this functionality clear.

    SetSelection() takes an index as it's argument, so you need to calculate the proper index. Assuming each new page is appended to the end of the wx.Notebook, you should be able to use the wx.Notebook.GetPageCount() function to calculate the total number of pages, and thus the index of the final page. Your code should look like this:

    def displayFreeNodes(self, event):
    
        [...]
    
        index = self.notebook.GetPageCount() - 1 #get the index of the final page.
        self.notebook.SetSelection(index) #set the selection to the final page
    

    EDIT
    It seems I have slightly misunderstood the question. The OP wants to be able to choose which tab to open based on the user clicking the appropriate item in a wx.ListCtrl object.

    The easiest way to do this would be to ensure that the items always appear in the wx.ListCtrl in the same order of they appear in the wx.Notebook. That means that clicking index 0 of the list opens index 0 in the notebook, clicking 1 opens tab 1, and so on. In that case you need to catch wx.EVT_LIST_ITEM_SELECTED and bind it to a method similar to the following:

    def handleListItemClick(event):
        index = event.GetIndex() #this will return the index of the listctrl item that was clicked
        self.notebook.SetSelection(index) #this will open that same index in notebook