18

I'm writing an application that needs to use an indicator. I've done this in the past using PyGTK and GTK2, using as reference this document: https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators#Python_version

However, that only works with PyGTK and GTK2. Things have changed since then, and I need to find some good documentation, a tutorial or a good example to learn how it works.

Also, one thing that the previously mentioned document doesn't describe at all, is how to add sub-menus to an indicator. I hope someone can shed some light on this, as well as how to integrate with category indicators if that's done using the same tool.

Thanks.

4 Answers 4

20

This is my trial code for gtk3 and appindicator which creates a indicator for GPaste.

Basically,

from gi.repository import AppIndicator3 as AppIndicator

in order to use appindicator for gtk3 applications which is provided by package gir1.2-appindicator3.

Here is the AppIndicator3 documentation.

pygtk will be deprecated for Gtk3 and you have to go through GObject-Introspection route for developing Gtk3 applications in python. You can refer to PyGObject documentation. Instead of

import pygtk, gtk, gdk, gobject, pango  

etc you should do

from gi.repository import Gtk, Gdk, Pango, GObject  

For studying a working code, you could view Kazam which has moved to gtk3 from gtk2 and uses appindicator3.

There is a package gir1.2-appindicator as well which seems to be same as using python-appindicator as they both provide usage for gtk2 appplication which is:

from gi.repository import AppIndicator

OR

import appindicator

Some information in this blog post as well.

5
  • I went with AppIndicator3. But does this mean that AppIndicator 1 is a direct port of python-appindicator whereas AI3 is a new version that isn't backported? Feb 27, 2012 at 21:32
  • It seems that way. I loaded appindicator 0.1 from python shell and then tried loading appindicator3 which gave me this error RepositoryError: Requiring namespace 'Gtk' version '3.0', but '2.0' is already loaded. So it seems appindicator 0.1 works with gtk2 i.e. pygtk and appindicator3 and above if any works with gtk3 Feb 28, 2012 at 4:08
  • 1
    Ah, I get it. It's not version 3 of AI. It's AI for GTK3 :) Feb 28, 2012 at 8:50
  • I've also noticed this blog entry discussing the use of AppIndicator3, which you might find interesting. Feb 28, 2012 at 10:17
  • 2
    Just a note, most of these links are dead. Jan 23, 2014 at 21:44
13

Here's a stupid simple scaffold application that has a config window, a main window, and an app indicator.

#!/usr/bin/env python3.3

from gi.repository import Gtk
from gi.repository import AppIndicator3 as appindicator

class MyIndicator:
  def __init__(self, root):
    self.app = root
    self.ind = appindicator.Indicator.new(
                self.app.name,
                "indicator-messages",
                appindicator.IndicatorCategory.APPLICATION_STATUS)
    self.ind.set_status (appindicator.IndicatorStatus.ACTIVE)
    self.menu = Gtk.Menu()
    item = Gtk.MenuItem()
    item.set_label("Main Window")
    item.connect("activate", self.app.main_win.cb_show, '')
    self.menu.append(item)

    item = Gtk.MenuItem()
    item.set_label("Configuration")
    item.connect("activate", self.app.conf_win.cb_show, '')
    self.menu.append(item)

    item = Gtk.MenuItem()
    item.set_label("Exit")
    item.connect("activate", self.cb_exit, '')
    self.menu.append(item)

    self.menu.show_all()
    self.ind.set_menu(self.menu)

  def cb_exit(self, w, data):
     Gtk.main_quit()

class MyConfigWin(Gtk.Window):
  def __init__(self, root):
    super().__init__()
    self.app = root
    self.set_title(self.app.name + ' Config Window')

  def cb_show(self, w, data):
    self.show()

class MyMainWin(Gtk.Window):
  def __init__(self, root):
    super().__init__()
    self.app = root
    self.set_title(self.app.name)

  def cb_show(self, w, data):
    self.show()

class MyApp(Gtk.Application):
  def __init__(self, app_name):
    super().__init__()
    self.name = app_name
    self.main_win = MyMainWin(self)
    self.conf_win = MyConfigWin(self)
    self.indicator = MyIndicator(self)

  def run(self):
    Gtk.main()

if __name__ == '__main__':
  app = MyApp('Scaffold')
  app.run()
1
  • This example still works in 20.04 with small changes: #!/usr/bin/env python3, and add import gi, gi.require_version('Gtk', '3.0'), gi.require_version('AppIndicator3', '0.1'). I also needed to sudo apt install gir1.2-appindicator3-0.1.
    – mivk
    Jul 29, 2021 at 11:13
9

Just in case someone might find it useful, I made a minimal app indicator with Python, GIR and GTK3. It reads CPU speeds from /proc/cpuinfo every few seconds and displays them.

See here: https://bitbucket.org/cpbotha/indicator-cpuspeed/src

0
8

Here is an example of reading cpu temperature. copy an icon named temp-icon.png/svg in the script directory

from gi.repository import Gtk, GLib
from gi.repository import AppIndicator3 as appindicator
import os

def cb_exit(w, data):
   Gtk.main_quit()

def cb_readcputemp(ind_app):
# get CPU temp
   fileh = open(
      '/sys/devices/platform/thinkpad_hwmon/subsystem/devices/coretemp.0/temp1_input',
    'r')
  ind_app.set_label(fileh.read(2), '')
  fileh.close()
  return 1


ind_app = appindicator.Indicator.new_with_path (
  "cputemp-indicator",
   "temp-icon",
   appindicator.IndicatorCategory.APPLICATION_STATUS,
    os.path.dirname(os.path.realpath(__file__)))
ind_app.set_status (appindicator.IndicatorStatus.ACTIVE)

# create a menu
menu = Gtk.Menu()
menu_items = Gtk.MenuItem("Exit")
menu.append(menu_items)
menu_items.connect("activate", cb_exit, '')
menu_items.show()
ind_app.set_menu(menu)
GLib.timeout_add(500, cb_readcputemp, ind_app)
Gtk.main()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .