2

I am new to Python and GUI programming. I was trying to learning both by doing a small application. In my application, a background process should run always and show the user's some fictional quota via appindicator. Here is my code:

#!/usr/bin/env python

import pyjsonrpc
from gi.repository import Gtk
from gi.repository import AppIndicator3 as appindicator
import thread
import glib

ind = None

def start_gtk_main():
    ind = appindicator.Indicator.new(
                                  "example-simple-client",
                                  "indicator-messages",
                                  appindicator.IndicatorCategory.APPLICATION_STATUS)

    ind.set_status (appindicator.IndicatorStatus.ACTIVE)
    ind.set_label('NA', '')

    menu = Gtk.Menu()
    menu_quit = Gtk.MenuItem("Quit")
    menu_quit.connect("activate", quit_app)
    menu.append(menu_quit)
    menu_quit.show()

    ind.set_menu(menu)

    try:
        thread.start_new_thread(update_ind_label, ())
    except:
        print "Error: unable to start thread"

    Gtk.main()

def quit_app(self):
    Gtk.main_quit()

def update_ind_label():
    value = glib.timeout_add_seconds(5, handler_timeout)

def handler_timeout():
    url = "http://localhost/jsonrpc-server/"
    http_client = pyjsonrpc.HttpClient(url)
    response = http_client.call("getQuota", 2)
    quota = response.get('quota')
    ind.set_label(quota+'%', '')
    return True

if ind is None:
    start_gtk_main()

The problem is whenever glib's timeout_add_seconds fire the callback function handler_timeout, it gives me segmentation fault error.

I also tried without thread like:

# ....other code....
glib.timeout_add_seconds(5, handler_timeout)
Gtk.main()
# ....other code....

But it gives me the same error.

I saw many similar questions around Internet, most of them suggested to use GLib's or GObject's timeout function or threads but none is working in my case. Can anyone tell me what I'm doing wrong here?

FYI, My OS is Xubuntu 13.10.

3
  • please can you pastebin your entire code - there doesnt appear to be any import statements in your code - maybe you are using a mixture of gtk2 and gtk3 libraries that wont work and causes segmentation faults? – fossfreedom May 2 '14 at 17:58
  • Where is appindicator coming from? Are you importing it somewhere else? – No Time May 2 '14 at 18:33
  • I have updated my question and now the code snippet contains the full python code. Thanks. – moshfiqur May 2 '14 at 18:56
5

Replace:

import glib

with:

from gi.repository import GLib as glib

And the code should work as is, although you need a global ind at the beginning of start_gtk_main(), otherwise ind is created local to the function and you get an exception in handler_timeout() that ind is None.

4
  • Yup, you did it. Working like a charm. Thanks a ton :) – moshfiqur May 2 '14 at 22:04
  • Can you please tell me the reason behind the solution? As I'm newbie would like to learn such tips and tricks. – moshfiqur May 2 '14 at 22:13
  • @sparrow I suspect a buggy interaction between python-gi (from gi.repository import ...) and python-gobject (import glib). It would take more debugging to figure out exactly why we are crashing here. It looks like it can't find the handler_timeout() function when the timeout is reached. In general best not to mix the two. – Jason Conti May 2 '14 at 22:28
  • 2
    @JasonConti: it's not buggy, they are not meant to be used together! Just like you can't mix the old static PyGTK bindings with the new dynamic GObject introspection method. The issue with the segmentation fault is that the old method can't detect if the new method is already loaded. You should get a normal error mesage the other way around. – Timo May 3 '14 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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