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.

In some of the ubuntu programs (ubuntu control panel, system settings), but not e.g. in banshee, the top part of the window contains elements in dark tone (with the Ambience theme). But I cant find a standard widget that does this automatically.

Are these colors all set by hand (instead of standard widget+theme)? And if they are set by hand, where do they come from in the theme (what are the parameters in gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color)) ?

EDIT: It does not seem to be a simple Gtk.Toolbar. If I run the following code:

from gi.repository import Gtk
window = Gtk.Window()
window.set_default_size(200, -1)
window.connect("destroy", lambda q: Gtk.main_quit())
toolbar = Gtk.Toolbar()
window.add(toolbar)
toolbutton = Gtk.ToolButton(stock_id=Gtk.STOCK_NEW)
toolbar.add(toolbutton)
window.show_all()
Gtk.main()

I get a window like this: enter image description here which does not have a dark tone for the toolbar.

EDIT2: Although the 'toolbar with special context' answer by j-johan-edwards is true in most of the programs, it is not the case in the ubuntuone-control-panel. This program has a GtkVBox which can include any range of widgets (unlike a toolbar). I'm still unable to determine how the gtk-theme knows how to paint that part of the window. enter image description here

But anyway: for now a toolbar is enough for me...

share|improve this question
add comment

2 Answers 2

up vote 19 down vote accepted
+50

Do you mean these?

GTK3 Toolbar

They're just Gtk.Toolbars. The reason some applications like Banshee don't use them is that they haven't yet ported to GTK+ 3, and received the new theming capabilities that enable toolbars like that.

To port your own Python application to GTK+ 3, you need to use PyGObject instead of PyGTK. As of 12.04, Quickly will generate PyGObject projects by default.

You also need to add primary-toolbar to the toolbar style context. Like so:

toolbar = Gtk.Toolbar()
context = toolbar.get_style_context()
context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

applying that context to the question example results in this:

demo

share|improve this answer
    
I added an example of a Gtk.Toolbar that does not look like dark. So I guess it is not a simple Gtk.Toolbar? –  xubuntix Oct 18 '11 at 9:10
    
Gtk.get_major_version() says 3, but I'm still getting the old toolbar. This is after a from gi.repository import Gtk in both python2 and python3. –  Stefano Palazzo Oct 18 '11 at 11:31
1  
The PyGI demo from the link you've posted doesn't have them either. Maybe app developers have to apply the styling themselves? –  Stefano Palazzo Oct 18 '11 at 13:06
    
perfect, thanks! –  xubuntix Oct 18 '11 at 18:20
    
Thanks for this been banging my head against a wall all morning!! should of searched here first. –  Shutupsquare Jun 24 '12 at 9:54
add comment

With regards to the second part of your question, which was "How to add VBox to the toolbar", all you have to do is wrap it inside a Gtk.ToolItem, eg:.

...
self.toolbar = Gtk.Toolbar()
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
tool_item = Gtk.ToolItem()
tool_item.add(self.box)
self.toolbar.insert(tool_item, 0)
...

You can make it simpler by creating a helper function or extending Gtk.Toolbar, for example:

custom_toolbar.py

from gi.repository import Gtk

class CustomToolbar(Gtk.Toolbar):
    def __init__(self):
        super(CustomToolbar, self).__init__()
        ''' Set toolbar style '''
        context = self.get_style_context()
        context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

    def insert(self, item, pos):
        ''' If widget is not an instance of Gtk.ToolItem then wrap it inside one '''
        if not isinstance(item, Gtk.ToolItem):
            widget = Gtk.ToolItem()
            widget.add(item)
            item = widget

        super(CustomToolbar, self).insert(item, pos)
        return item

It simply checks if the object you try to insert is a ToolItem, and if not, it wraps it inside one. Usage example:

main.py

#!/usr/bin/python
from gi.repository import Gtk
from custom_toolbar import CustomToolbar

class MySongPlayerWindow(Gtk.Window):
    def __init__(self):
        super(MySongPlayerWindow, self).__init__(title="My Song Player")
        self.set_size_request(640, 480)

        layout = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(layout)

        status_bar = Gtk.Statusbar()
        layout.pack_end(status_bar, False, True, 0)

        big_button = Gtk.Button(label="Play music")
        layout.pack_end(big_button, True, True, 0)

        ''' Create a custom toolbar '''
        toolbar = CustomToolbar()
        toolbar.set_style(Gtk.ToolbarStyle.BOTH)        
        layout.pack_start(toolbar, False, True, 0)

        ''' Add some standard toolbar buttons '''
        play_button = Gtk.ToggleToolButton(stock_id=Gtk.STOCK_MEDIA_PLAY)
        toolbar.insert(play_button, -1)

        stop_button = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_STOP)
        toolbar.insert(stop_button, -1)

        ''' Create a vertical box '''
        playback_info = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, margin_top=5, margin_bottom=5, margin_left=10, margin_right=10)

        ''' Add some children... '''
        label_current_song = Gtk.Label(label="Artist - Song Name", margin_bottom=5)
        playback_info.pack_start(label_current_song, True, True, 0)

        playback_progress = Gtk.ProgressBar(fraction=0.6)
        playback_info.pack_start(playback_progress, True, True, 0)

        '''
        Add the vertical box to the toolbar. Please note, that unlike Gtk.Toolbar.insert,
        CustomToolbar.insert returns a ToolItem instance that we can manipulate
        '''
        playback_info_item = toolbar.insert(playback_info, -1)
        playback_info_item.set_expand(True)        

        ''' Add another custom item '''       
        search_entry = Gtk.Entry(text='Search')
        search_item = toolbar.insert(search_entry, -1)
        search_item.set_vexpand(False)
        search_item.set_valign(Gtk.Align.CENTER)

win = MySongPlayerWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

It should look like this

share|improve this answer
    
this is great, thank you! –  xubuntix Jan 20 '12 at 8:02
    
For the record, you can do this with glade, too. GtkToolItem doesn't appear in the palette of widgets. Instead you have to right-click on the GtkToolbar in the object tree and select "Edit" to open a separate editing window. Go to the "Hierarchy" tab and add a new object to the hierarchy. The default object-type is "Button," but you can also select "custom." That "custom" item is in fact an empty GtkToolItem. Then you can select that empty item using the regular glad interface and add widgets to it normally. This allowed me to add a GtkEntry widget to a GtkToolbar in a matter of seconds. –  monotasker Aug 9 '12 at 18:42
add comment

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.