joedborg
joedborg

Reputation: 18353

Refresh Gtk.StatusIcon in python

I'm trying to write a script that checks certain things and display a notification in the tray if something's wrong. In this example, I'm looking at the age of a file.

What I can't seem to work out how to do is change the icon once gtk.main() is running.

import os, gtk
from time import time, sleep
from datetime import datetime

class HeartbeatTrayIcon(object):
    """
    Use GTK to create an object in the system tray
    and manipulate icon shown if there is an issue.
    """
    def __init__(self):
        rx = os.path.getmtime("test")
        self.statusIcon = gtk.StatusIcon()
        if (time() - rx) > (60*60*24):
            self.statusIcon.set_from_stock(gtk.STOCK_CANCEL)
        else:
            self.statusIcon.set_from_stock(gtk.STOCK_APPLY)
        self.statusIcon.set_tooltip("Last heartbeat received at %s" % datetime.fromtimestamp(int(rx)).strftime('%H:%M:%S %d-%m-%Y'))

    def tray(self):
        gtk.main()

if __name__ == "__main__":
    i = HeartbeatTrayIcon()
    i.tray()

Upvotes: 0

Views: 810

Answers (1)

Frédéric Hamidi
Frédéric Hamidi

Reputation: 262939

You are only checking the file's age in the constructor for HeartbeatTrayIcon, so that code only runs once.

I'd suggest using gobject.idle_add() to register a callback function that performs the check. That function will be called when the application is idle (i.e. when no higher-priority events exist in the queue):

import os, gtk, gobject
from time import time, sleep
from datetime import datetime

class HeartbeatTrayIcon(object):
    """
    Use GTK to create an object in the system tray
    and manipulate icon shown if there is an issue.
    """
    def __init__(self):
        self.statusIcon = gtk.StatusIcon()

    def check(self):
        rx = os.path.getmtime("test")
        if (time() - rx) > (60*60*24):
            self.statusIcon.set_from_stock(gtk.STOCK_CANCEL)
        else:
            self.statusIcon.set_from_stock(gtk.STOCK_APPLY)
        self.statusIcon.set_tooltip("Last heartbeat received at %s" \
            % datetime.fromtimestamp(int(rx)).strftime('%H:%M:%S %d-%m-%Y'))
        return True

    def tray(self):
        gobject.idle_add(self.check)
        gtk.main()

if __name__ == "__main__":
    i = HeartbeatTrayIcon()
    i.tray()

In passing, note that your heartbeat message does not seem to do what you're looking for: it will always print the modification time of the file, not the time of the last check. You might want to store the value returned by time()in a variable and use that instead of rx.

Upvotes: 3

Related Questions