Monday, September 21, 2009

Python + Tkinter and Python + Gtk

Remembering that Python was intended as a scripting language, compare these two HelloWorld from Python.

First, Tkinter for Tk as in Tcl/Tk

from Tkinter import *
root = Tk()

class HelloWorld:

def __init__(self):
  widget = Button(root, text = 'Hello World', command = self.quit)
  widget.pack()

def quit(self):
  print "Hello World"
  import sys
  sys.exit()

HelloWorld()
root.mainloop()

Now to compare the same minimal HelloWorld with Gtk.  First, install Gtk+  ( and on Windows XP  that means get all of the dependencies - the DLL's - on the path.)

import pygtk
pygtk.require('2.0')
import gtk

class HelloWorld:
def hello(self, widget, data=None):
print "Hello World"

def delete_event(self, widget, event, data=None):
print "delete event occurred"
return False

def destroy(self, widget, data=None):
   gtk.main_quit()

def __init__(self):
   self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   self.window.connect("delete_event", self.delete_event)
   self.window.connect("destroy", self.destroy)
   self.window.set_border_width(10)
   self.button = gtk.Button("Hello World")
   self.button.connect("clicked", self.hello, None)
   self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
   self.window.add(self.button)
   self.button.show()
   self.window.show()

def main(self):
   gtk.main()

if __name__ == "__main__":
    hello = HelloWorld()
    hello.main()

Whatever the merits of Gtk+ as a cross-platform C GUI framework for general purpose languages, something looks to have gone wrong with the Python library PyGtk.

Even with Tk itself, something comparable occurs when using Tk from Haskell versus using Tk from OCaml.  Probably  expect was the Tcl "killer app" but Tk is what most developers know of Tcl today.  Tk was also an early mainstay of Ruby.  Here is the HelloWorld demo using Gtk+ from the Ruby-Gnome team:

# Copyright (c) 2002,2003 Ruby-GNOME2 Project Team
require 'gtk2'

button = Gtk::Button.new("Hello World")
button.signal_connect("clicked") {
    puts "Hello World"
}

window = Gtk::Window.new
window.signal_connect("delete_event") {
    puts "delete event occurred"
#true
   false
}

window.signal_connect("destroy") {
   puts "destroy event occurred"
   Gtk.main_quit
}

window.border_width = 10
window.add(button)
window.show_all

Gtk.main

Now this is a little better, but compared to Ruby + Tk we are at almost double the lines of code.

To see a really elegant use of Tk, see the QTk framework for Oz, the language.  I'm fiddling with a QCurl variant for Oz just now.  I added some notes on OCaml and labltk over at wikia.com

No comments: