How to display an image next to a menu item? - python

I am trying to get an image to appear next to a menu item but it isn't working.
In order to make this as simple as possible, I have created a very simple example below that highlights the problem:
import pygtk
pygtk.require('2.0')
import gtk
class MenuExample:
def __init__(self):
window = gtk.Window()
window.set_size_request(200, 100)
window.connect("delete_event", lambda w,e: gtk.main_quit())
menu = gtk.Menu()
menu_item = gtk.ImageMenuItem("Refresh")
img = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
img.show()
menu_item.set_image(img)
menu.append(menu_item)
menu_item.show()
root_menu = gtk.MenuItem("File")
root_menu.show()
root_menu.set_submenu(menu)
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
menu_bar = gtk.MenuBar()
vbox.pack_start(menu_bar, False, False, 2)
menu_bar.show()
menu_bar.append(root_menu)
window.show()
def main():
gtk.main()
return 0
if __name__ == "__main__":
MenuExample()
main()
When I run the application, it shows the menu item, but it does not show the image next to it.
OS: Ubuntu 10.04 64-bit
Python version: 2.6.5

Hmmm... it turns out the answer was that my desktop theme had disabled icons for menus. (Who knows why.)
After enabling the option, the icons now show up.

Related

Python Gtk 3.0: How to grab focus inside Notebook

I'm trying to set the focus to an Entry input field. If I put it inside a Box, I can set the focus via the grab_focus method. But if the Entry is inside a Notebook, it is not focused.
Example code:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Simple Notebook Example")
self.set_border_width(3)
self.notebook = Gtk.Notebook()
self.add(self.notebook)
self.page1 = Gtk.Box()
self.page1.set_border_width(10)
self.page1.add(Gtk.Label(label="Default Page!"))
self.notebook.append_page(self.page1, Gtk.Label(label="Plain Title"))
self.note = Gtk.Entry()
self.note.set_activates_default(True)
self.note.set_text("")
self.page1.add(self.note)
self.page2 = Gtk.Box()
self.page2.set_border_width(10)
self.page2.add(Gtk.Label(label="A page with an image for a Title."))
self.notebook.append_page(
self.page2, Gtk.Image.new_from_icon_name("help-about", Gtk.IconSize.MENU)
)
self.note.grab_focus() # does not work
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
How can I focus self.note inside the notebook?
Thanks for any help!
As it turns out, you can only grab focus to visible widgets.
Calling grab_focus after show_all makes the example work:
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
win.note.grab_focus()
Gtk.main()

How to override default right-click menu in Gtk FileChooserWidget

The gtk FileChooserWidget shows a context menu on right-click with "add to bookmarks", "show hidden files", and "show size column" options. I would like to override this menu with a custom menu.
Creating a menu on right-click from other gtk widgets (window, eventbox) is easy and there are a lot of tutorials out there showing how to do it.
I can't seem to get events from a gtk filechooser widget, however. The "on_button_press_event" callback in the following code never gets called:
#!/usr/bin/env python
import gtk
class file_chooser_test():
def __init__(self):
window = gtk.Window()
window.connect("delete_event", lambda w,e: gtk.main_quit())
chooser = gtk.FileChooserWidget()
chooser.set_size_request(600, 400)
chooser.add_events(gtk.gdk.BUTTON_PRESS_MASK)
chooser.connect("button-press-event", self.on_button_press_event)
window.add(chooser)
window.show_all()
gtk.main()
def on_button_press_event(self, widget, event=None):
print "event is: ", event
if __name__ == "__main__":
test = file_chooser_test()
Can anyone shed any light on how to override the default right-click menu on the GTK FileChooserWidget?
Thanks!

Python GTK3 toolbar accelerator doesn't work

I'm following the Python GTK+ 3 Tutorial, and the accelerators I'm putting for the toolbar actions don't work. Here's a program showing the problem, roughly based on that tutorial. There's a menu action with N shortcut and a toolbar action with X shortcut. Menu action's shorcut works, toolbar action's one doesn't, even though the actions are created identically.
from gi.repository import Gtk
UI_INFO = """
<ui>
<menubar name='TestMenubar'>
<menu action='FileMenu'>
<menuitem action='MenuAction' />
</menu>
</menubar>
<toolbar name='TestToolbar'>
<toolitem action='ToolbarAction' />
</toolbar>
</ui>
"""
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Test")
self.set_default_size(200, 100)
action_group = Gtk.ActionGroup(name="test_actions")
self.add_menu_action(action_group)
self.add_toolbar_action(action_group)
uimanager = self.create_ui_manager()
uimanager.insert_action_group(action_group)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
menubar = uimanager.get_widget("/TestMenubar")
box.pack_start(menubar, False, False, 0)
toolbar = uimanager.get_widget("/TestToolbar")
box.pack_start(toolbar, False, False, 0)
self.add(box)
def add_menu_action(self, action_group):
action_filemenu = Gtk.Action(name="FileMenu", label="File")
action_group.add_action(action_filemenu)
action = Gtk.Action(name='MenuAction',
label="Menu action",
stock_id=Gtk.STOCK_NEW)
action.connect('activate', self.on_menu_action)
action_group.add_action_with_accel(action, 'N')
def add_toolbar_action(self, action_group):
action = Gtk.Action(name='ToolbarAction',
label="Press me",
stock_id=Gtk.STOCK_MEDIA_STOP)
action.connect('activate', self.on_toolbar_action)
action_group.add_action_with_accel(action, 'X')
def on_menu_action(self, widget):
print 'Menu action'
def on_toolbar_action(self, widget):
print 'Toolbar action'
def create_ui_manager(self):
uimanager = Gtk.UIManager()
uimanager.add_ui_from_string(UI_INFO)
self.add_accel_group(uimanager.get_accel_group())
return uimanager
window = MyWindow()
window.connect("delete-event", Gtk.main_quit)
window.show_all()
Gtk.main()
How can I make pressing X shortcut invoke the callback?
(The reference for GTK+ 3 say that add_action_with_accel is deprecated, so there's surely a better way to create the accelerators, but the doc doesn't show the way, and I couldn't find a better tutorial.)
Faced with the same problem. I asked a similar question on gtk 3 programming specific to gedit plugins here. I found that the menubar shortcuts are the only ones that work. So just introduce a menu item which does exactly what your tool item does. Preserve your tool item in order to provide flexibility to the user, but do not assign it any shortcut. i.e. add_action, not add_action_with_accel would be enough to add it to the action group.

Why does this pygtk TextView refuse to wrap?

I have a textview inside a scrolledwindow that refuses to wrap to words/chars/wordschars no matter how I set the wrap mode. It simply extends the size of itself and its containers as it pleases. Here's an example:
import gtk
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(256,256)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
view = gtk.TextView()
view.set_wrap_mode(gtk.WRAP_CHAR)
scroll.add(view)
window.add(scroll)
window.show_all()
gtk.main()
How can I make it wrap? If it matters, I need the parent window to be resizeable by the user, just not the text.
You need to set the size request on the TextView's container (which is scroll in your example), not the Window or the TextView itself.
Try the following:
import gtk
if __name__ == "__main__":
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
view = gtk.TextView()
view.set_wrap_mode(gtk.WRAP_CHAR)
scroll.set_size_request(256, 256)
scroll.add(view)
window.add(scroll)
window.show_all()
gtk.main()
I just ran your code and word wrapping seems to be working fine. What are you running it on? I'm using PyGTK 2.22 on Ubuntu 11.04.

Putting other widgets in gtk.Menu

I'd like to be able to put a gtk.ProgressBar in my gtk.Menu, but since menus only takes gtk.MenuItems and its subclasses, what I've done instead is take a plain gtk.MenuItem and tried adding my progress bar as a child to that. Since gtk.MenuItem is a subclass of gtk.Bin, it should be able to hold pretty much any widget.
Example:
menu = gtk.Menu()
item = gtk.MenuItem()
button = gtk.ProgressBar()
button.pulse()
button.show()
item.add(button)
item.show()
menu.append(item)
This runs just fine without pygtk complaining at all. However, my progress bar is simply not shown:
If I replace the progressbar with a gtk.Label, it's shown just fine.
Now to my questions:
How do I know which widgets it will take?
How do I trick it into letting me put other widgets in there?
This is a limitation of Ubuntu's Application Indicators, see this question at askubuntu.
Your example code works here(I tested it by modifying a pygtk example that I will paste below).
Maybe its an issue with the rest of your code or your theme?
#!/usr/bin/env python
# example menu.py
import pygtk
pygtk.require('2.0')
import gtk
class MenuExample:
def __init__(self):
# create a new window
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(200, 100)
window.set_title("GTK Menu Test")
window.connect("delete_event", lambda w,e: gtk.main_quit())
# Init the menu-widget, and remember -- never
# show() the menu widget!!
# This is the menu that holds the menu items, the one that
# will pop up when you click on the "Root Menu" in the app
menu = gtk.Menu()
### MODIFIED PART!! ###
item = gtk.MenuItem()
button = gtk.ProgressBar()
button.pulse()
button.show()
item.add(button)
item.show()
menu.append(item)
#### END MODIFIED PART ####
# This is the root menu, and will be the label
# displayed on the menu bar. There won't be a signal handler attached,
# as it only pops up the rest of the menu when pressed.
root_menu = gtk.MenuItem("Root Menu")
root_menu.show()
# Now we specify that we want our newly created "menu" to be the
# menu for the "root menu"
root_menu.set_submenu(menu)
# A vbox to put a menu and a button in:
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
# Create a menu-bar to hold the menus and add it to our main window
menu_bar = gtk.MenuBar()
vbox.pack_start(menu_bar, False, False, 2)
menu_bar.show()
# Create a button to which to attach menu as a popup
button = gtk.Button("press me")
button.connect_object("event", self.button_press, menu)
vbox.pack_end(button, True, True, 2)
button.show()
# And finally we append the menu-item to the menu-bar -- this is the
# "root" menu-item I have been raving about =)
menu_bar.append (root_menu)
# always display the window as the last step so it all splashes on
# the screen at once.
window.show()
# Respond to a button-press by posting a menu passed in as widget.
#
# Note that the "widget" argument is the menu being posted, NOT
# the button that was pressed.
def button_press(self, widget, event):
if event.type == gtk.gdk.BUTTON_PRESS:
widget.popup(None, None, None, event.button, event.time)
# Tell calling code that we have handled this event the buck
# stops here.
return True
# Tell calling code that we have not handled this event pass it on.
return False
# Print a string when a menu item is selected
def menuitem_response(self, widget, string):
print "%s" % string
def main():
gtk.main()
return 0
if __name__ == "__main__":
MenuExample()
main()

Categories

Resources