Skip to content

Instantly share code, notes, and snippets.

@candidtim
Last active December 3, 2021 18:50
Show Gist options
  • Save candidtim/5663cc76aa329b2ddfb5 to your computer and use it in GitHub Desktop.
Save candidtim/5663cc76aa329b2ddfb5 to your computer and use it in GitHub Desktop.
Ubuntu AppIndicator to show Chuck Norris jokes
# This code is an example for a tutorial on Ubuntu Unity/Gnome AppIndicators:
# http://candidtim.github.io/appindicator/2014/09/13/ubuntu-appindicator-step-by-step.html
import os
import signal
import json
from urllib2 import Request, urlopen, URLError
from gi.repository import Gtk as gtk
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Notify as notify
APPINDICATOR_ID = 'myappindicator'
def main():
indicator = appindicator.Indicator.new(APPINDICATOR_ID, os.path.abspath('sample_icon.svg'), appindicator.IndicatorCategory.SYSTEM_SERVICES)
indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
indicator.set_menu(build_menu())
notify.init(APPINDICATOR_ID)
gtk.main()
def build_menu():
menu = gtk.Menu()
item_joke = gtk.MenuItem('Joke')
item_joke.connect('activate', joke)
menu.append(item_joke)
item_quit = gtk.MenuItem('Quit')
item_quit.connect('activate', quit)
menu.append(item_quit)
menu.show_all()
return menu
def fetch_joke():
request = Request('http://api.icndb.com/jokes/random?limitTo=[nerdy]')
response = urlopen(request)
joke = json.loads(response.read())['value']['joke']
return joke
def joke(_):
notify.Notification.new("<b>Joke</b>", fetch_joke(), None).show()
def quit(_):
notify.uninit()
gtk.main_quit()
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal.SIG_DFL)
main()
@Zibri
Copy link

Zibri commented Dec 18, 2016

python2 myappindicator_v5.py

myappindicator_v5.py:10: PyGIWarning: Gtk was imported without specifying a version first. Use gi.require_version('Gtk', '3.0') before import to ensure that the right version gets loaded.
from gi.repository import Gtk as gtk
myappindicator_v5.py:11: PyGIWarning: AppIndicator3 was imported without specifying a version first. Use gi.require_version('AppIndicator3', '0.1') before import to ensure that the right version gets loaded.
from gi.repository import AppIndicator3 as appindicator
myappindicator_v5.py:12: PyGIWarning: Notify was imported without specifying a version first. Use gi.require_version('Notify', '0.7') before import to ensure that the right version gets loaded.
from gi.repository import Notify as notify

@Zibri
Copy link

Zibri commented Dec 18, 2016

python3 myappindicator_v5.py

Traceback (most recent call last):
File "myappindicator_v5.py", line 8, in
from urllib2 import Request, urlopen, URLError
ImportError: No module named 'urllib2'

@osh2ep
Copy link

osh2ep commented Mar 19, 2017

@Zibri: use Requests instead.

@apollothethird
Copy link

Single Click Functionality using set_secondary_activate_target

Can you tell us how to add the middle click functionality to your code so that it'll take one click on the indicator to see the latest joke?

This functionality is provided by the set_secondary_activate_target() method.

Inserting this line menu.indicator.set_secondary_activate_target(joke) in this section doesn't give errors in the Eclipse IDE:

def build_menu():
    menu = gtk.Menu()
    item_joke = gtk.MenuItem('Joke')
    item_joke.connect('activate', joke)
    menu.indicator.set_secondary_activate_target(joke)
    menu.append(item_joke)
    item_quit = gtk.MenuItem('Quit')
    item_quit.connect('activate', quit)
    menu.append(item_quit)
    menu.show_all()
    return menu

However attempting to run it, it fails with these errors:

Traceback (most recent call last):
  File "/home/users/l/j/ljames/workspace/pythontest/src/test.py", line 55, in <module>
    main()
  File "/home/users/l/j/ljames/workspace/pythontest/src/test.py", line 24, in main
    indicator.set_menu(build_menu())
  File "/home/users/l/j/ljames/workspace/pythontest/src/test.py", line 32, in build_menu
    menu.indicator.set_secondary_activate_target(joke)
AttributeError: 'Menu' object has no attribute 'indicator'

By the way, I removed the version runtime errors by added these lines:

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')

Thanks in advance for any suggestions or comments from anyone!

-- L. James

--
L. D. James
[email protected]
www.apollo3.com/~ljames

@apollothethird
Copy link

After constant testing, the following works:

Adding a parameter to the build_menu() function works:

indicator.set_menu(build_menu(indicator))

and

def build_menu(indicator):

Clicking the icon with the middle button will bring up the joke.

This is the new code:

# This code is an example for a tutorial on Ubuntu Unity/Gnome AppIndicators:
# http://candidtim.github.io/appindicator/2014/09/13/ubuntu-appindicator-step-by-step.html

import os
import signal
import json

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')

from urllib2 import Request, urlopen, URLError

from gi.repository import Gtk as gtk
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Notify as notify


APPINDICATOR_ID = 'myappindicator'

def main():
    indicator = appindicator.Indicator.new(APPINDICATOR_ID, os.path.abspath('sample_icon.svg'), appindicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu(indicator))
    notify.init(APPINDICATOR_ID)
    gtk.main()

def build_menu(indicator):
    menu = gtk.Menu()
    item_joke = gtk.MenuItem('Joke')
    item_joke.connect('activate', joke)
    indicator.set_secondary_activate_target(item_joke)
    menu.append(item_joke)
    item_quit = gtk.MenuItem('Quit')
    item_quit.connect('activate', quit)
    menu.append(item_quit)
    menu.show_all()
    return menu

def fetch_joke():
    request = Request('http://api.icndb.com/jokes/random?limitTo=[nerdy]')
    response = urlopen(request)
    joke = json.loads(response.read())['value']['joke']
    return joke

def joke(_):
    notify.Notification.new("<b>Joke</b>", fetch_joke(), None).show()

def quit(_):
    notify.uninit()
    gtk.main_quit()

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()

-- L. James

--
L. D. James
[email protected]
www.apollo3.com/~ljames

@jmarroyave
Copy link

jmarroyave commented Sep 27, 2017

Thanks for the tutorial

Python 3 and liburl

https://gist.github.com/jmarroyave/a24bf173092a3b0943402f6554a2094d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment