5. The class constructor: __init__

We're going to see these points in a natural order when coding it. Please look at the final example section to see a functional applet i'm doing for check the cpu throttling states on the new centrino processors and speedstep. Visit the cpudyn utility for more info.

5.1. Some instance variable definitions


        self.timeout_interval = 1000        
        self.throttling_states = 0
        self.active_t_state = "T0"
        self.bus_activity = ""
        self.actual_cpu_state = "C1"
        self.lack_t_acpi = 0
        self.lack_p_acpi = 0
        self.dict = {}
        self.tooltip_text = ""
        self.checks = [0,0,0,0,0]
         

Here are the different variables that sample objects will use to keep itself updated.

5.2. The GTK widgets definition

First of all, we need to initializate the gnome applet with call to gnome.init(). Once this has been done, we can begin to pack the different widgets our applet will be compound of. and connect some callbacks to events in the common way, not the glade.XML one (see section 4.5.1)


        # initializate the gnome internals
        gnome.init("sample", "1.0")

        self.applet = applet

        self.tooltips = gtk.Tooltips()
        self.hbox = gtk.HBox()
        applet.add(self.hbox)

        # add the second button event for the popup menu and the enter mouse event to change the tooltip value
        self.ev_box = gtk.EventBox()
        self.ev_box.connect("button-press-event",self.button_press)
        self.ev_box.connect("enter-notify-event", self.update_info)
        self.hbox.add(self.ev_box)

        self.prog = gtk.ProgressBar()
        self.ev_box.add(self.prog)
      

This an example of a simple applet with a gtk.ProgressBar in a hbox, that mantain a gtk.Tooltip to show some info.

5.3. Optional timeout callback method

A common task when programming a gnome applet is to check if something has changed at the system level from time to time. This is resolved with gtk.timeout_add() method with a timeout_interval in milliseconds defined at the class variables section.

         gtk.timeout_add(self.timeout_interval,self.timeout_callback, self)

5.4. Connecting the "destroy" signal and show the applet

It's important to do this in order to avoid memory leaks when killing the applet process incorrectly.


        applet.connect("destroy",self.cleanup)
        applet.show_all()
    

5.5. Connecting signals and events to handlers

When connecting events to handlers we know there are at least two options with GTK programming: with or without glade user interface designer. In this example we will look at both possibilities. We'll use glade for the applet preferences window, as we just used the direct way of doing it with the connect() method before in the "GTK widgets" section.

5.5.1. Loading the interface with glade.XML()

It's quite simple to read a glade interface from pyGTK. All we need to do is to call to the gtk.glade.XML() method with the .glade file as parameter. After this, we'll define some variables for every widget we are going to use or modify, with gtk.get_widget('widget name') method. Finally, we must define the callbacks methods in the class definition. Calling signal_autoconnect() with the class instance as parameter, that in this case will be "self". So, we we'll have this at [callbacks methods] section:


    def on_properties_delete_event(self,widget,event):
        widget.hide()
        return gtk.TRUE

    def on_checkbutton1_toggled(self,widget):
        self.checks[0] = widget.get_active()
        print self.checks
    def on_checkbutton2_toggled(self,widget):
        self.checks[1] = widget.get_active()
        print self.checks
    def on_checkbutton3_toggled(self,widget):
        self.checks[2] = widget.get_active()
        print self.checks
    def on_checkbutton4_toggled(self,widget):
        self.checks[3] = widget.get_active()
        print self.checks
    def on_checkbutton5_toggled(self,widget):
        self.checks[4] = widget.get_active()
        print self.checks
    

Those were our callback methods and now we'll see the connection of them to the glade interface:

And the [reading glade XML optionally] section:


        wT = gtk.glade.XML("/path/to/file/glade/file.glade")
        # the way to do it with sample_globals defined will be something like:
        #   wT = gtk.glade.XML(os.path.join(pglobals.glade_dir, "sample.glade"))
        #this is optional if you want to have some widget reference kept
        preferencesDialog = wT.get_widget('properties')
        self.preferences = preferencesDialog
        wT.signal_autoconnect(self)
    

We can see that the on_properties_delete_event() handler is used to hide the properties window. It returns gtk.TRUE in order to avoid the destruction of the dialog so we can reuse it later. Remember that returning gtk.TRUE in an event handler stops the event propagation in GTK+. We show this dialog when the user clicks on the popup preferences option.

5.5.2. Using the gtkWidget.connect() method

This is the common way of connecting events to handlers, as seen at the "GTK widgets" section. It could be useful when packing some widgets dinamically.


          self.ev_box = gtk.EventBox()
          self.ev_box.connect("button-press-event",self.button_press)
          self.ev_box.connect("enter-notify-event", self.update_info)