Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I've got a Python app that uses a Gtk.Notebook widget to display different pages. Each of these pages contain a different set of widgets, and I've noticed that the 'tallest' widget in terms of vertical space defines the overall vertical size of the notebook.

But I'd actually like my app to resize the pages to not waste vertical space, and adapt, that is, get resized to the same vertical size as the widget they contain. This resize should happen when I select each page.

Test app showing undesired vertical space

Here's the sample code to generate this notebook (the example contains a widget per page for the sake of simplicity)

So in short, how can I dinamically resize notebook pages upon selecting them, so that their vertical space is adapted to be the same as their child widget?

share|improve this question

2 Answers 2

I do not know a nice answer, but I have a work-around for you:

The basic idea is that you need a container widget as the parent widget in each page (do not place e.g. a label directly in the page), and you can hide/show everything except the container (If you hide the container as well, the page will disappear).

This solution should work for otherwise arbitrary widget hierarchies.

from gi.repository import Gtk

class NotebookWindow():
    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file('notebook.ui')
        self.builder.get_object('window1').connect('delete-event',
            Gtk.main_quit)
        notebook = self.builder.get_object('notebook1')
        notebook.connect("switch-page", self.on_notebook1_switch_page)
        self.on_notebook1_switch_page(notebook, None,
                                      notebook.get_current_page())

    def on_notebook1_switch_page(self, widget, label, page):
        for p in range(widget.get_n_pages()):
            container = widget.get_nth_page(p)
            if not p == page:
                for c in container.get_children():
                    try:
                        c.hide_all()
                    except AttributeError:
                        c.hide()
            else:
                for c in container.get_children():
                    try:
                        c.show_all()
                    except AttributeError:
                        c.show()


if __name__ == '__main__':
    notebookwindow = NotebookWindow()
    Gtk.main()

In my original answer I recorded and re-instated the requested sizes. This does not work in general, because the requested size is only a minimal size. I would have to record a maximum size, in order for this to work, though.

share|improve this answer
    
That's exactly what I needed, thanks! I tested it to work on rev 2 of the example. However, when testing it with the real code it did not seem to work. I've tracked it down to be because there the widgets in the real app are not put directly inside the notebook page, but rather they are contained within a grid in each page. Rev 3 of the example illustrates this situation. –  David Planella May 31 '12 at 10:37
    
I'll accept the answer, as it's a valid workaround for the question. I'm still stuck with my code with the grid, though. I'm unsure about opening a new question since it will be too localized, but in any case, any ideas why the latest example code with the grid is not doing the resize? Thanks! –  David Planella May 31 '12 at 10:38
    
Hi, I'll think about it... But its always ok, when you wait a while before you accept an answer, maybe someone else knows something better. I think it would make more sense to un-accept my answer than to write a new one with a minor change. –  xubuntix May 31 '12 at 11:05
    
@DavidPlanella ok, added a fix for your more general problem. My guess is that you will soon wish there would be a toolkit with a more pythonic syntax. If thats the case, have a look at [kivy](kivy.org) :-) –  xubuntix May 31 '12 at 11:26
    
Excellent, thanks! Ok, I'll unaccept the answer for now as suggested, and if no other one comes up, I'll accept it again after testing your fix :) –  David Planella May 31 '12 at 11:28

IF the actual notebook widget is not needed, but is merely a way to keep similar content together and provide a way to switch between them, then there might be better/simpler solutions. Here is one that was in the end used for Qreator:

the main idea is to use a container like a Gtk.Box (called page_box in the example below) and keep only one item visible. You also need a list with the content of each page, each packed into a single widget (e.g. a Gtk.Grid).

for page in page_list:
    self.ui.page_box.add(page.grid)

Here page_list is a simple list of page objects, where the page object has a grid property (the Gtk.Grid containing all the page content).

At last, you need to provide a way to switch between the contents, e.g. with a set of buttons, each calling a switch method with the corresponding page_id when clicked:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

This is not a literal answer to the question, but it might solve the same problem.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.