I have a notebook that contains pages with tabs that have close buttons in them. When you click on the button, the page in that tab is then removed from the notebook( closed).
The problem is that when the tab closes, the memory is never freed, because there seems to be something still referencing the destroyed page.
Here is some sample code for my notebook:
notebook = gtk.Notebook
def create_tab():
page = gtk.Label( "THis is a page")
page.show()
tab = gtk.HBox()#The custom tab-label widget
tab_label = gtk.Label( "Tab")
tab_label.show()
tab.pack_start( tab_label)
tab_close = gtk.Button()
tab_close.set_image(gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU))
tab_close.connect( 'clicked', destroy_tab, page )
tab_close.show()
tab.pack_end( tab_close)
tab.show()
notebook.append_page(page, tab)
def destroy_tab( widget, data=None):
page_num = notebook.page_num( data )
notebook.remove_page( page_num )
data.destroy()
The create_tab function is a callback added to a button’s clicked signal, so I can add as many pages to the notebook as I’d like. But when the page is removed from the notebook, through the destroy_tab callback, the page is successfully removed from the notebook, but the memory is never freed.
This link outlines the same problem I’m having. And one thing it suggests is that there is still a reference to the page through the custom widget set as the tab_label. I’ve also tried destroying the custom widget, even recursively destroying all of its children but still can’t seem to figure out what is still referencing this page to keep it in memory. What could be the problem?
I managed to figure out, through
gc.getreferrers()that there was a circular referencebetween the close button and the page that it was closing. Through further testing, I found out that it’s of no fault of my own, but in the way that a
GtkNotebookseems to link the two when they’re added to the notebook. I did manage to get rid of that circular reference simplyby creating a custom button that holds a reference to the widget itself, so then, when the button is destroyed, that widget reference is set to
Noneand that seems to successfully get rid of the reference.However, this still doesn’t seem to clear up the memory behind the page after it is closed.
Here’s the revamped code:
And then, in the code you would use the button like so:
And that does the trick! The reference disappears when the destroy method is called on the button