Version 46 of gnocl or PyGtk?

Updated 2008-08-14 03:23:28 by peterc

WJG For the past ten years or so I've been a mixed Windows/Linux user. Jolted along by a presentation that I made at an OpenAdvantage [L1 ] seminar earlier this year, I decided to put Windows on the back-burner and spend my time running Linux. Putting OS considerations aside, I needed to think about re-working my custom apps running under Tcl/Tk on Windows. Windows and MacOS discourage us from fiddling about with the appearance of things, whereas Linux, well... Now, that I've settled into things and got Gnome looking the way I like it, I want my tcl apps to fall in line. Not an easy thing to do in Tk - under Linux as everything still looks like Motif. So the dilemma is GTk or Tk? Well -Gtk. But what about Tcl? If we refer to the Gtk+ developer site [L2 ] we do find bindings listed and, as seems par for everything else, Python is the preferred choice. But why should it be? The following piece of Python code puts a single button in the middle of a toplevel window. The link for PyGtk [L3 ].


 #!/usr/bin/env python

 # example helloworld.py

 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):
        print "destroy signal occurred"
        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()

Here's the equivalent in Gnocl, effectively one line of code. In PyGtk, the coder still needs to manually made connections between events and handlers which Gnocl does automatically. Isn't the purpose of scripting to reduce code-recreation the minimum, not merely to make recreation easier?


 #!/bin/sh
 # the next line restarts using tclsh \
 exec tclsh "$0" "$@"

 package require Gnocl

 gnocl::window -child [gnocl::button -text "Hello World" -onButtonPress exit] -onDelete exit

Which one would you choose? Find the Gtk C code here [L4 ].

LV Another consideration - check out Tile, which, as Ttk, comes with Tk starting in Tcl/Tk 8.5. Perhaps it would be worthwhile seeing how to improve the Ttk-Gtk cooperation?

LBarret Tile is very promising but the argument for gnocl is pretty weak : mainly better syntatic sugar. Furthemore, this is vanilla GTk; many people use autoconnect mechanisms that make the difference less important. Comparing the other example seen on the gnocl mainpage may show that the difference is not that important.

WJG Thanks for the comments -but. I'm not dealing with issues regarding the Tk-Tile debate, but how to get the best out of easy scripting with Gtk. If I want to run my apps on Windows, I'd leave them the way they are, 'cause they look pretty good and the rendering of widgets is just fine to me. If I'm running Linux, then I want it to adhere to my desktop theme, whatever that might be. Tk doesn't do that, and neither, I suspect, will Tile. [ LV Actually, one of the major ideas behind Tile, in my understanding, is that it would in fact recognize theme changes, at least on MacOS X and Windows. I don't know what it does on Linux right now, but the framework should be in place to do it. However, you are not interested, so no need to go farther on that point.] Let's keep comments salient to the content of the page which is the ease of building Gtk based UI applications in a tcl script. I would have thought this a cause for celebration in itself. Check the code by using it and not just look the screen shots, try the real alternatives: building Gtk apps in C!

WJG Fellow Wiki users, have the courtesy not to swap code which has been placed on this page for a purpose. Someone changed the Python code to a clip which was not correct. I have restored it back to what it should be.

Nickname WJG, have the courtesy not to massively over-inflate code to prove a point. The Python code you posted contains additional behavior not found in the Gnocl code, and in addition is needlessly verbose.

WJG(31/10/07) Nickname, please read the posting. This isn't my code but that from the PyGtk website. Besides, apart from the code that you posted didn't work (not on my machine anyway) it's still more verbose than the gnocl code! So, reciprocate the courtesy. Leave postings be; if you wish to make a point with reasoned debate then add it, don't censure others! If I'm wrong, or there's a better view, fine I'll be the first to listen and fix any errors.

Here's a useful link on Wikiquette [L5 ]

For those who really need it, here's Nickame's posting...

peterc 2008-08-14: It's worth looking at the Tile-GTK theme [L6 ] by Georgios Petasis. Even the 0.1 screenshot at http://www.ellogon.org/~petasis/tcl/tile-gtk-dev-0.1.png looks pretty good. I'd really suggest sticking with Tile if at all possible.


 #!/usr/bin/env python

 # example helloworld.py

 import gtk

 window = gtk.Window ()
 window.connect ('destroy', gtk.main_quit)
 button = gtk.Button ('Hello World')
 button.connect ('clicked', gtk.main_quit)
 window.add (button)
 window.show_all ()
 gtk.main ()

default WJG, the example may still be more verbose than the Gnocl example, but very less so. The original comparison is still quite unfair. FYI, I corrected (and shortened) the Python example above. Anyway, GUI design with code still sucks -- you need an interactive way to design UIs and Gnocl doesn't provide that. For scripting, you usually need only quite limited capabilities and there are more suitable toolkits for that.

Besides, I have problems with Gnocl seemingly doing certain things "automagically", like entering the GTK main loop. What if you want to nest the main loop?


WJG (13/08/08) I'm not so certain that 'GUI design with code still sucks'. My take on the matter is that interactive GUI design produces more code than necessary. At best it's a means of reducing the programmers exposure to verbose code or, more likely, is used to workaround a lack of solid GUI coding skill. Good GUI design comes from clearly thinking through the various controls necessary for an application and perhaps even sketching the intended layout. Working with interactive tools often leads to just fiddling around with widgets or trying to make something visually complex. But who am I to comment? Conversations with other developers leads me to form the opinion that too many programmers relish in the complexity of their code, even if the code is terse even for themselves to explain. To compare the Gnocl offering with the pyGTk script, is I now admit, an injustice -the Gnocl commands offer so much more! The forthcoming release of Gnocl, for instance, has a few nice enhancements. Here's one line of code for example.

    set txt [ gnocl::text \
     -baseColor xffffcd \
     -baseFont { Sans 14 } \
     -onButtonPress { bpProc %w %b %s } \
     -onButtonRelease { brProc %w %b %s } \
     -onKeyPress { kpProc %w %k %s } \
     -onKeyRelease { krProc %w %k %s } ]

Apart from automatic support for scrolling windows, event and signal management, the latest version supports tag events and extended default settings support and the familiar Tk style substitution strings. How many lines of PyGtk code do we need for this? Or, if you wish, how many lines of Glade XML code?. Which is easier to understand as a scripter? And, of course, the Gnocl code is totally reusable! A PyGtk app, is a PyGtk app. Gnocl is a scripting extension to Tcl just like Tk.

To be fair, the Gnocl C source code ought to be compared with the PyGtk script as its is at this level that the same Gtk library functions are called.

Gnocl is intended to simplify the process of developing Gtk applications. I'm sure that PyGtk does make the development of Gtk applications easier than pure Gtk C code, but then, its largely acting as some sort of glue; one still needs to know the innards of the Gtk Libraries to make sense of PyGtk. Gnocl, on the other hand, enables new or established Gtk developers to move straight into creating their new Gtk applications.

Finally, the mainloop. This can be called explicitly if needed with the gnocl::mainLoop. But then, why would it need to be nested elsewhere?


Category GUI