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