29a.ch

Entries tagged “pygtk”

PyGTK Exception Hook

screenshot I wrote a little exception hook for pygtk applications. When an exception occurs it will show a dialog with a full stack trace obtained using cgitb.

import gtk, gobject
import sys

_ = lambda s: s

def scrolled(widget, shadow=gtk.SHADOW_NONE):
    window = gtk.ScrolledWindow()
    window.set_shadow_type(shadow)
    window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    if widget.set_scroll_adjustments(window.get_hadjustment(),
                                      window.get_vadjustment()):
        window.add(widget)
    else:
        window.add_with_viewport(widget)
    return window


class ExceptionDialog(gtk.MessageDialog):
    def __init__(self, etype, evalue, etb):
        gtk.MessageDialog.__init__(self, buttons=gtk.BUTTONS_CLOSE, type=gtk.MESSAGE_ERROR)
        self.set_resizable(True)
        self.set_markup(_("An error has occured:\n%r\nYou should save "
                "your work and restart the application. If the error "
                "occurs again please report it to the developer." % evalue))
        import cgitb
        text = cgitb.text((etype, evalue, etb), 5)
        expander = gtk.Expander(_("Exception Details"))
        self.vbox.pack_start(expander)
        textview = gtk.TextView()
        textview.get_buffer().set_text(text)
        expander.add(scrolled(textview))
        self.show_all()

def install_exception_hook(dialog=ExceptionDialog):
    old_hook = sys.excepthook
    def new_hook(etype, evalue, etb):
        if etype not in (KeyboardInterrupt, SystemExit):
            d = dialog(etype, evalue, etb)
            d.run()
            d.destroy()
        old_hook(etype, evalue, etb)
    new_hook.old_hook = old_hook
    sys.excepthook = new_hook

if __name__ == "__main__":
    install_exception_hook()
    gobject.idle_add(lambda: 1/0)
    gobject.idle_add(gtk.main_quit)
    gtk.main()

Stepped scales with pygtk

The Scale Widgets that come with gtk ignore step_incr from the adjustment when the user drags the slider. So there is no way to specify that you only want to use increments of 0.5 or 1.0. So here's how to do it:

class Scale(object):
    """A scale that adheres to increment steps"""
    def __init__(self):
        self.connect("change-value", self.adjust)

    def adjust(self, range, scroll, value):
        adj = self.get_adjustment()
        lower = adj.get_property('lower')
        upper = adj.get_property('upper')
        incr = adj.get_property('step-increment')
        value -= (value % incr)
        self.set_value(min(max(lower, value), upper))
        return True


class VScale(gtk.VScale, Scale):
    def __init__(self, *args):
        gtk.VScale.__init__(self, *args)
        Scale.__init__(self)

class HScale(gtk.HScale, Scale):
    def __init__(self, *args):
        gtk.HScale.__init__(self, *args)
        Scale.__init__(self)
Author

Jonas Wagner Jonas Wagner
Software Engineer
Zürich, Switzerland

More about me

Follow 29a_ch on Twitter

Experiments

screenshot screenshot screenshot screenshot

More Experiments

Latest Posts Tags Archive Links

guitarmasterclass.net (guitar lessons)