Defining VCL-like framework for Python

Alexander Staubo alexspam at mop.no
Tue May 18 22:39:44 EDT 1999


I've just delved headfirst into what I'm trying to convince myself is a 
small project. In this article I will throw around some ideas; forgive 
the high rant-factor but it's kinda late.

I would be very grateful for comments, theoretical guidance, and 
practical assistance in implementing the project.

Before we start, anyone who immediate wants to murmur "Oh no, not another 
windowing toolkit thing," please avoid this discussion or open your mind. 
To my defense, though, this isn't just about windowing.

Based on positive experiences with Inprise's (formely Borland's) 
excellent Windows-based development tool, Delphi, and its offsprings 
C++Builder and JBuilder, I'd like to build an experimental framework that 
imitates the paradigm used by Delphi's VCL -- "Visual Component Library". 
For the uninitiated, the VCL is admittedly not an ingenious piece of 
engineering, but it works extremely well as a programming paradigm, and 
is built on a sensible and sound component design philosophy that lets a 
user alternate between using a "black box" (calling methods, accessing 
properties, and implementing event handlers, etc.) or an "open box" 
metaphor (using inheritance to implement new controls, overriding 
functionality, using knowledge of class internals to alter behaviour, 
etc.). Delphi's component framework relies on its streaming facilities 
(which resemble Python's but are not supported intrinsically by language, 
although the system uses Delphi's RTTI support extensively for run-time 
discovery), and provides a number of pieces that fit together to give you 
object persistence, hierchical components, controls and windows, graphics 
tools, etc.

Delphi is particularly good -- especially compared to such toolkits as 
Microsoft's MFC -- because it offers clean OOP concepts, a reasonably 
complete component architecture, and the ability to do pure, and very 
flexible, black box programming if you don't care, or you don't want to 
care, about the internals of the modules you're using. As a side-effect, 
a newbie can create Delphi programs without any code at all, since the 
IDE permits you to create forms, put components and controls on them, and 
create relationship visually by filling in properties. It's not something 
that is realistic for hardcore developers, but they reap the benefits of 
this component-ized mode of programming, too.

Imho, Python needs a better windowing toolkit than is provided by 
Tcl/Tkinter today. That's just me. Furthermore, Python does not have (at 
least afaik) a component-based system for building applications. Python 
provides many facilities that the VCL defines -- such as persistence and 
RTTI-like mechanisms -- but afaik there is no well-defined protocol for 
creating cross-module components.

I'm imitating the VCL structure in Python because it has, during Delphi's 
lifetime, proven to be an effective and flexible design as well as 
implementation, and a programming paradigm well-suited to Python: for 
example, Python is OO, has an even better streaming/persistence system 
than Delphi, even better support for run-time discovery, integration with 
other languages, COM/Java/CORBA, and so forth. I'm not aiming to mimic 
the VCL to a T, though; the idea is to glean the nice bits and forfeit 
others in the name of designing Good Python. It would be stupid, for 
example, to reimplement Delphi's persistence system, when we can use 
Python's native, optimized pickling abilities. On the other hand, the 
system should provide pickling facilities specifically geared towards 
streaming components into a common format, much like Delphi streams forms 
to "DFM" files. On the same note, the Python VCL should provide a basic 
set of components and visual controls that can be implemented on any 
platform (eg., forms/windows, edit boxes, labels, buttons), and no more: 
additional, complex, platform-specific controls (such as Win32 list 
views, or BeOS Replicants, or Mac tree views) should be part of some 
extra platform package, not necessarily even part of the project proper.

I am implementing as much as possible in Python in order to maximize on 
its dynamic capabilities, and only use C or C++ for implementing 
platform-specific windowing and environment code. As for the windowing 
stuff, which after all constitutes > 90% of the Delphi VCL, I have the 
Win32 integration mapped out in my head, but I have no experience with 
other windowing systems such as X or the Mac. I have rudimentary 
understanding of the BeOS APIs. I wouldn't mind starting out by 
implementing basic Win32 support first, and then go on from there; not to 
be single-minded (I love BeOS), but to minimize the time to actually get 
the project off the ground; it would be nice to say we have a working 
implementation on Windows and are anticipating support for other 
platforms soon. Anyway, cross-platform compatibility is a goal.

One definite guideline here is not to rely on third-party windowing 
system support: in other words, the project will not use wxPython, 
Tkinter or any other library, although not precluding the ability to 
write controls that use such libraries internally.

My big "hmm" right now is how -- or where -- to split the implementation 
across Python and C/C++. Or rather, which parts should be implemented in 
C/C++? There are a few options here, and each has its pros and cons:

- Let all the VCL be Python-implemented, and have controls which need to 
interface with the underlying window system be wrappers. For example, the 
Python control EditBoxControl (analoguous to TEditBox in the Delphi) 
would channel events to an internal object variable implemented by a 
platform-specific, C/C++-implemented module, like so:

  class EditBoxControl(Control):
    def __init__(self, ...):
      if Win32:
        __InternalControl__ = Win32Controls.Edit()
      elif BeOS:
        __InternalControl__ = BeOSControls.Edit()
      else:
        ...
      __InternalControl__.Color = self.Color;  # or whatever
    def __getattr__(self, name):
      if name == "Text":
        return __InternalControl__.Text
      else:
        ...

Pros: Reasonably clean, isolates platform-specific modules. Cons: The 
C/C++-implemented module must probably be rigidly defined, and so must 
follow the "lowest common denominator" in order to provide compatible 
functionality on platforms.

- Variation of the above: Instead of defining a generic interface to the 
platform-specific control, let the Python-implemented control be 
platform-specific as well. So:

  if Win32:

    class EditBoxControl(Control):
      def __init__(self, ...):
        __InternalControl__ = Win32.EditBoxControl()
        self.DC = __InternalControl__.GetDC()
        __InternalControl__.SetMsgMask(-1)  # or whatever

  elif BeOS:
 
    ...

Pros: As above, plus each control can be implemented efficiently in 
Python, as well. Cons: Often one control for every platform, and 
identical behaviour might not be guaranteed.

- Controls are implemented completely by C/C++ module, and provided to 
Python in "shadow" classes that wrap around the platform-specific 
implementation. Pros: Simple to think about, reasonably clean, easy to 
support lots of platforms through conditional directives. Cons: This will 
leave very little for Python; most of the VCL will be pure C/C++, and 
while we reap the benefits of Python's persistence facilities etc., the 
code will be more C and less Python in spirit (my analysis). Also this 
solution suffers from the same problems as above: Lots of ifdefs, 
possible "breach of contract" in design differences, etc.

There are quite probably other solutions I have not thought of 
(admittedly 4 am is not the best time to think these things through).

As a proof-of-concept application for the new Python VCL I vote for a 
Python IDE with an integrated debugger. Talk about ambitious. But think 
about it: We need an IDE, and we need a windowing toolkit that doesn't 
suck, and it could be a good idea to combine the two.

Note that the project I have delineated here is not about "reproducing 
Delphi in Python". At least not yet. :) I want mainly to steal a few good 
ideas, improve others, and create something that makes Python more 
valuable to those "visual" programmers out there -- one of whom I don't 
necessarily count myself, although I sure miss a good windowing toolkit 
in Python; it deserves one.

-- 
Alexander Staubo
mailto:alex at mop.no
http://www.mop.no/~alex




More information about the Python-list mailing list