PyFLTK - an underrated gem for GUI projects

A

aum

Hi all,

I've been doing a fair bit of python gui programming on and off, jumping
between different widget sets along the way, from anygui, to pythoncard,
to tkinter/PMW, then to wxPython/wxGlade, and have now settled on a python
gui API that seems to get barely a mention - PyFLTK.

PyFLTK (http://pyfltk.sourceforge.net) is a SWIG-generated Python
wrapper around the multiplatform FLTK widget set ('Fast Light Tool Kit'
- http://fltk.sourceforge.net). In recent months, this wrapper has
stabilised to the point where it's fit for production projects.

A recent development that's given PyFLTK even more power is the
companion utility program, 'flconvert', which takes gui layout files
(created with the FLTK 'fluid' gui designer program) and turns them into
importable Python modules that Simply Just Work.

Every widget set has its place, and I feel this applies in no small part
to PyFLTK.

To me, wxPython is like a 12-cylinder Hummer, with fuzzy dice hanging
from the mirror, fridge and microwave in the back, and DVD consoles on
every seat, towing a campervan - absolute power and luxury, giving 8mpg
if you're lucky.

wxPython has the cost of a massive disk and memory footprint. A 'hello,
world' turned into a windoze exe with py2exe weighs in at around 15MB,
and takes 6-10 seconds to load up on a 2GHz Athlon box, about as long as
Photoshop! For large and intricate apps, wxPython is a logical choice,
but for smaller progs it's serious overkill IMHO.

Whereas PyFLTK feels more like an average suburban 4-door sedan giving
70mpg, nothing too flash, but easy to drive, easy to park and generally
comfortable, and easy to look after. The widget set is pretty simple,
but covers all the basics and includes good rich-text features in
listboxes, as well as an html viewer that supports html2.0 and parts of
html3.0.

Some of the things I'm liking about PyFLTK include:
- way less code to get things done
- some nice automagic, for instance in setting up tiling (similar to
wx's splitter windows)
- an absolute minimum of 'voodoo programming' (which was a constant
bugbear for me with tkinter)
- apps compile small, and start up fast
- a really good designer program - fltk's 'fluid' program is light
years ahead of wxglade imho

Also, FLTK's intuitive, semantically clear API makes it really
approachable for newcomers. One can write a 'hello, world' in 5 lines:

import fltk
label = "something here" # to stop string being gc'ed
w = fltk.Fl_Window(100, 100, 300, 200, label)
w.show()
fltk.Fl.run()

So I hope this humble message might inspire some folks to have a serious
look at pyfltk. For many situations, PyFLTK can take you to break-even
point quickly, and deliver net savings in time and effort after that.
 
P

Paul Rubin

aum said:
To me, wxPython is like a 12-cylinder Hummer, ...
Whereas PyFLTK feels more like an average suburban 4-door sedan

Interesting. What would Tkinter be at that car dealership? What
about PyGTK?
 
A

aum

Interesting. What would Tkinter be at that car dealership? What
about PyGTK?

Tkinter - would be like an old Holden with abundant interchangeable parts,
but needing a cultivated intuitive feel and much tinkering to get the
engine and everything else to work just right. Needing to pull over and
change a few jumpers on the PC board of the radio to get it on the right
channel.

PyGTK - no experience there

Pythoncard - a 50cc motorbike with training wheels
 
P

Peter Hansen

aum said:
To me, wxPython is like a 12-cylinder Hummer, with fuzzy dice hanging
from the mirror, fridge and microwave in the back, and DVD consoles on
every seat, towing a campervan - absolute power and luxury, giving 8mpg
if you're lucky.

wxPython has the cost of a massive disk and memory footprint. A 'hello,
world' turned into a windoze exe with py2exe weighs in at around 15MB,
and takes 6-10 seconds to load up on a 2GHz Athlon box, about as long as
Photoshop! For large and intricate apps, wxPython is a logical choice,
but for smaller progs it's serious overkill IMHO.

While I don't disagree with your characterization above, I don't think
your numbers are quite right.

The wxPython program below, py2exe'd on my machine (1.6GHz Pentium M),
comes to only 12MB (2-3MB of which is Python itself), and takes 1-2
seconds to load (actually less than one second after the first
invocation following a fresh reboot).

Yes, 12MB is pretty heavy, but if it's taking that long to load I think
something might be wrong on your machine.

(Python 2.4, wx 2.6.1.0, py2exe 0.6.3, Win XP SP2)

-Peter
-------------------------------

import wx

class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Hello")

self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Show(True)


def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.DrawText('Hello, world!', 10, 10)


app = wx.PySimpleApp()
f = Frame()
app.MainLoop()
 
B

Bugs

Peter said:
The wxPython program below, py2exe'd on my machine (1.6GHz Pentium M),
comes to only 12MB (2-3MB of which is Python itself), and takes 1-2
seconds to load (actually less than one second after the first
invocation following a fresh reboot).

And even 12MB seems heavy, unless I created my exe with py2exe
incorrectly...
I created the singlefile gui demo app that comes with py2exe (test_wx)
and it's only 4.6MB on my WinXP machine, 3.6MB when compressed with UPX.
Anyone else get the same results?
 
S

Steve Holden

aum said:
Tkinter - would be like an old Holden with abundant interchangeable parts,
but needing a cultivated intuitive feel and much tinkering to get the
engine and everything else to work just right. Needing to pull over and
change a few jumpers on the PC board of the radio to get it on the right
channel.

PyGTK - no experience there

Pythoncard - a 50cc motorbike with training wheels
Less of the "old", if you don't mind ...

regards
Steve
 
P

Peter Hansen

Bugs said:
And even 12MB seems heavy, unless I created my exe with py2exe
incorrectly...
I created the singlefile gui demo app that comes with py2exe (test_wx)
and it's only 4.6MB on my WinXP machine, 3.6MB when compressed with UPX.
Anyone else get the same results?

That's probably correct, but the singlefile option is new to me. Can
you provide your setup.py so we can compare? What I used was simply this:

from distutils.core import setup
import py2exe
setup(
windows=[dict(script='wxhello.py')]
)

The 12MB measurement was made by looking at the Properties for the
"dist" folder that results.

(I think using singlefile is comparing oranges and motorbikes, however,
since it almost certainly is compressing a lot, and when the program
runs it decompresses first. Although practically this masks the issue,
technically there is still probably 12MB of data involved and the OP's
point still stands that that's quite a bit of data for a simple Hello.)

-Peter
 
B

Bugs

Hi Peter,
I just used the setup.py that comes in the singlefile/gui sample.
However, py2exe does still also require the msvcr71.dll runtime as well,
which is 340kb. Here it is, it's a bit lengthy:

# If run without args, build executables, in quiet mode.
if len(sys.argv) == 1:
sys.argv.append("py2exe")
sys.argv.append("-q")

class Target:
def __init__(self, **kw):
self.__dict__.update(kw)
# for the versioninfo resources
self.version = "0.6.1"
self.company_name = "No Company"
self.copyright = "no copyright"
self.name = "py2exe sample files"

################################################################
# A program using wxPython

# The manifest will be inserted as resource into test_wx.exe. This
# gives the controls the Windows XP appearance (if run on XP ;-)
#
# Another option would be to store it in a file named
# test_wx.exe.manifest, and copy it with the data_files option into
# the dist-dir.
#
manifest_template = '''
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="5.0.0.0"
processorArchitecture="x86"
name="%(prog)s"
type="win32"
/>
<description>%(prog)s Program</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
'''

RT_MANIFEST = 24

test_wx = Target(
# used for the versioninfo resource
description = "A sample GUI app",

# what to build
script = "test_wx.py",
other_resources = [(RT_MANIFEST, 1, manifest_template %
dict(prog="test_wx"))],
## icon_resources = [(1, "icon.ico")],
dest_base = "test_wx")

################################################################

setup(
options = {"py2exe": {"compressed": 1,
"optimize": 2,
"ascii": 1,
"bundle_files": 1}},
zipfile = None,
windows = [test_wx],
)
 
R

Roger Binns

aum said:
To me, wxPython is like a 12-cylinder Hummer, with fuzzy dice hanging
from the mirror, fridge and microwave in the back, and DVD consoles on
every seat, towing a campervan - absolute power and luxury, giving 8mpg
if you're lucky.

A word of support for wxPython:

- It comes with a nice demo app that shows every single supported
widget and editable code for playing with them so you can tweak
to try new things.

- It supports printing, drag and drop and various similar niceties
on each platform.

- Mac is a first class citizen (support isn't perfect but it is
better than "good enough"). The FLTK docs mention Mac a few
times but usually just Unix and Windows.

- It fully supports Unicode. (It looks like the under development
FLTK 2.0 uses UTF-8 in some places but doesn't look like this
release is imminent.)

- There is a half decent HTML widget. (The FLTK one is only a
quarter decent :)

- You get the native look and feel on each platform and native widgets
are used wherever possible. (I can't tell what FLTK does).

- Various other corner things are covered as needed by more complex
apps such as audio, ActiveX on Windows, stock icons, online help,
calendar controls, directory and file selectors, a grid/table etc
etc

As is usually the case, each developer only uses 10% of the functionality of
the toolkit available, but it is a different 10% for each! My 10% includes
printing and drag and drop which are missing from most of the toolkits you
listed. I also insist on native widgets wherever possible.

It is possible to make the wxPython smaller by having more DLLs each with
fewer widgets in it. That way you will only suck in the ones you use.

I do like that FLTK has the documentation style as PHP where users
can add comments to each page.

Roger
 
A

aum

A word of support for wxPython:

Most right you are, Roger. wx is a 5-star GUI library.
When advanced GUI features are needed, wx, gtk2 or qt are definitely the
way to go.

What I'm saying is that there are many basic projects being written for
these toolkits, whose functionality could be completely supported by
PyFLTK. When only a smaller set of widgets is needed, there's a stronger
case for using lighter widget libraries - especially FLTK, because you'll
get way more functionality per line of code, and finish your project
faster, than if using the bigger toolkits with their application-level red
tape - the extra lines of code you have to write to get things done.

If travelling off-road for a few weeks and driving over minefields in
enemy territory, take the Hummer. But for ordinary use, like commuting to
work, visiting friends, shopping etc, using anything more than the Honda
4-cylinder sedan is IMHO a waste of resources.

Similarly, coding something in wx when FLTK will suffice is a waste of
time, effort, disk space, CPU cycles and memory.
 
A

aum

PyFLTK is not a debian package - yet.
Is nobody interested, or is there a more specific reason ?

AFAIK, the maintainer feels it's still at release-candidate stage.
When he's happy with it, I'm sure he could be persuaded to make
arrangements to .deb it, or get someone else to.

In the meantime, it does build ok on Debian, provided you build/install
libfltk from source, and set the FLTK_HOME env var to point into it before
running the pyfltk setup.py, as per the instructions in pyfltk tarball.
 
J

Jorge Godoy

aum said:
What I'm saying is that there are many basic projects being written for
these toolkits, whose functionality could be completely supported by
PyFLTK. When only a smaller set of widgets is needed, there's a stronger
case for using lighter widget libraries - especially FLTK, because you'll
get way more functionality per line of code, and finish your project
faster, than if using the bigger toolkits with their application-level red
tape - the extra lines of code you have to write to get things done.

At least on Linux world, it is easier to find Qt or GTK than FLTK. Not having
to deploy new base libraries for another project when there are other
available is a big plus, IMHO. Specially if you have no control over the
politics of updating servers, installing extra software, etc. And it would
sound really weird asking the admin to install new software on the server or
on workstations to provide a GUI layer for a more complex project just after
using a lighter one... "Why not using the same stuff for both?" is the
question I hear from them.

Installing things mean, usually:

- checking licenses

- checking vulnerabilities

- convincing admin / IT staff that it is needed and there's no
"already installed" alternative

- maintenance

- tests on upgrading the environment

- tests on deployment (who knows if there's something that might cause
a clash or interfere with other apps?)

and a few more stuff. Doing all that just because one app might use a lighter
toolkit doesn't look interesting.

On the other hand, if the environment requires lighter libs -- the software
will be embedded in something --, then it is fine doing all these because of
that.
If travelling off-road for a few weeks and driving over minefields in
enemy territory, take the Hummer. But for ordinary use, like commuting to
work, visiting friends, shopping etc, using anything more than the Honda
4-cylinder sedan is IMHO a waste of resources.

You can choose only one vehicle and you don't know where you'll be sent.
Which will you pick?
Similarly, coding something in wx when FLTK will suffice is a waste of
time, effort, disk space, CPU cycles and memory.

If wx is already there, installing FLTK starts being a waste of resources,
disk space, CPU cycles, memory (it won't be shared with other apps...), etc.
 
E

egbert

PyFLTK is not a debian package - yet.
Is nobody interested, or is there a more specific reason ?
 
B

Bugs

Roger said:
It is possible to make the wxPython smaller by having more DLLs each with
fewer widgets in it. That way you will only suck in the ones you use.

I find this VERY interesting Roger, I've been contemplating making such
a request to the maintainer of wxPython (when he gets back). It would
be ideal if there was some way to break up the wx library into smaller
logical chucks so as little of wx as possible is distributed when
utilizing tools such as py2exe. Plus, there are parts of wx that aren't
wrapped by the wxPython classes that don't need to go anyways.
Do you have any more information to share on this Roger?
Thanks!
 
A

aum

Installing things mean, usually:
8><

Distilling what you've said, it would appear the essence of your argument
is "PyFLTK is less desirable because it's not popular", an argument
which, despite a level of pragmatic truth, does contain more than a little
bit of recursion.

Fortunately this thinking wasn't too widespread in the early days of wx
and wxPython.

I do respect wxPython. It's definitely a high-class gui environment.

But for smaller gui programs not needing the power of wx, I find I get
the job done much more quickly and effortlessly with PyFLTK.
 
J

Jeremy Sanders

aum said:
But for smaller gui programs not needing the power of wx, I find I get
the job done much more quickly and effortlessly with PyFLTK.

Interesting. I've found PyQt very easy to use too. I wonder how they compare
(providing you can GPL your app, of course).
 
F

Fredrik Lundh

Claudio said:
Running some of the test examples
(e.g. C:\Python24\pyfltk\test\doublebuffer.py)
I am getting an error I have never seen before:

==============================================================
TitleOfMessageBox:
Microsoft Visual C++ Runtime Library

TheMessage:
Runtime Error!

Program: C:\Python24\python.exe

The application has requested the Runtime to terminate it in an unusual
way.
Please content the application's support team for more information.
==============================================================

afaik, that's the default behaviour for an explicit call to abort() on Windows.

</F>
 
C

Claudio Grondi

So I hope this humble message might inspire some folks to have a serious
look at pyfltk. For many situations, PyFLTK can take you to break-even
point quickly, and deliver net savings in time and effort after that.

Animated by your posting I have downloaded:
fltk-1.1.6-source.zip (3.073.432 bytes)
pyFltk-1.1rc1.tar.gz (306.323 bytes)
..
I use Microsoft Windows 2000 (and/or XP) with installed
MSVC++ .NET 2003 compiler environment and I am running
Python version 2.4.2.

The compilation of FLTK run without problems and after some minor
adjustments I was also able to build and install pyFltk.

Running some of the test examples
(e.g. C:\Python24\pyfltk\test\doublebuffer.py)
I am getting an error I have never seen before:

==============================================================
TitleOfMessageBox:
Microsoft Visual C++ Runtime Library

TheMessage:
Runtime Error!

Program: C:\Python24\python.exe

The application has requested the Runtime to terminate it in an unusual
way.
Please content the application's support team for more information.
==============================================================

Also cube.py (which runs ok as fltk-1.1.6\test\cube.exe i.e. the genuine
FLTK test app as also the doublebuffer.exe does) crashes in the pyFLTK
version with:

C:\>C:\Python24\pyfltk\test\cube.py
Traceback (most recent call last):
File "C:\Python24\pyfltk\test\cube.py", line 218, in ?
form.show(len(sys.argv), sys.argv)
File "C:\Python24\Lib\site-packages\fltk.py", line 2164, in show
def show(*args): return _fltk.Fl_Window_show(*args)
TypeError: Swig director python method error: Error detected when calling
Fl_Group.handle.
argument number 1: a 'Fl_Group *' is expected, 'MyBox' is received

Most of the other test scripts seem to run ok.

Any hints about the possible reasons of the problems described above are
welcome.

It appears to me, that the
C:\Python24\Lib\site-packages\_fltk.pyd and the *.py files
is all what is required to run pyFltk, so there will be no problem for
pyFltk if I delete the genuine FLTK files - am I right?

Claudio
P.S. If someone is interested in getting the _fltk.pyd (the pyFLTK Windows
binary version for Python 2.4), he/she is welcome to let me know about it.
 
T

Tom Anderson

Interesting. What would Tkinter be at that car dealership?

A '70s VW Beetle - it's been going for ever, but it's still rock solid,
even if it does look a bit naff. Also, hippies love it.

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top