Everything good about Python except GUI IDE?

Steven D'Aprano steve at pearwood.info
Sun Feb 28 07:50:57 EST 2016


On Sun, 28 Feb 2016 07:44 pm, Chris Angelico wrote:

> On Sun, Feb 28, 2016 at 5:34 PM, Steven D'Aprano <steve at pearwood.info>
> wrote:
[...]
>> Drag-and-drop GUI builders have the same advantages over code as Python
>> has over languages with distinct compile/execute steps: rapid
>> development, prototyping, exploration and discovery. Of course, any
>> decent modern builder won't limit you to literally drag-and-drop, but
>> will offer functionality like duplicating elements, aligning them,
>> magnetic guides, etc.
> 
> Alright, but how do you go about doing, with a drag-and-drop builder,
> all those things we're used to with code - composing new named actions
> out of primitives, observing the changes to a program through source
> control, unit testing (maybe), and code review? 

These are all good questions. Let's see if I can give good answers:

(1) "composing new named actions" -- I'm not entirely sure what you mean. Do
you mean new named *widgets*? A good builder app should give you the
ability to Group widgets into a single element, this is functionality which
has existed in vector-drawing programs since at least MacDraw in 1984 so it
shouldn't be hard. This is composition, a fundamental, powerful and rich
design pattern for making new widgets (classes) out of simpler parts. If
objects have a name, now you can refer to CompositeMenuDateColourPicker by
name. You can copy it, paste it, replicate it 30 times, whatever you like.

Possibly the GUI builder will even add it to the "Insert Widget" menu, or
put it on the toolbar. Surely the builder app will use a plug-in
architecture to control what widgets are available. How easy is it to
create new plug-ins from within the builder? This is a "quality of
implementation" issue.

Presumably a modern GUI builder will have the ability to export to source
code, so you can export your CompositeMenuDateColourPicker to a file, then
re-use it over and over again in project after project.


(2) "source control" -- the world is full of document types that aren't
plain text source code, and people have found ways to manage collaborative
editing and change management for them. Why don't we ask game developers
how they manage changes to the non-code elements in their applications?
Textures, icons, player avatars, sound effects, maps, etc. Surely you don't
suggest that game developers edit their background images in a hex editor?

(3) "unit testing" -- I'm not sure that unit testing is what is needed for
the GUI elements of your application. It's more like integration testing,
to ensure that the entire application works together as a seamless whole.
I'm not sure what the state of the art in GUI application integration
testing is like. I suspect crap, judging by the state of the art in GUI
applications.

But whatever it is, it will surely operate the same regardless of whether
you have built the application using code or a graphical builder.

(The GUI framework itself may have some analogue to unit testing for the
individual widgets, but that's not your responsibility as the user of the
framework. It's not up to you to test that menus drop down when clicked,
but it is your responsibility to check that the right menus exist and that
they do what they are supposed to.)

(4) "code review" -- the usual way to review the graphical elements of a GUI
app is to call somebody over, sit them down at the running application, and
say "What do you think of this?". They will usually answer "that icon needs
to be a bit more to the left, and can you make that button blue instead of
green?".



> The only way I know of 
> to build a "function" in a DnD builder is to create a composite widget
> (eg "horizontal box containing label and entry field"), which is
> extremely useful, but limited - it's like saying that the only way to
> reuse code is single-inheritance.

A poor analogy. Composition is equivalent to multiple inheritance, except
without any of the weaknesses of MI.


> How would you create a higher-order 
> operation in a DnD builder? How would you write something that does
> some sort of sweep over a set of widgets and does the same thing to
> them?

In Hypercard, if it was a once-off processing task, I would create a button,
edit the button's script:

on mouseUp:
  -- my memory of HC syntax and functions is a bit rusty
  -- this may not be correct
  for btnNum in 1 to the number of buttons:
    if btnNum is the number of me:
      continue
    end if
    set the textsize of button btnNum to 9
    set the textstyle of button btnNum to bold,italic
    if the name of button btnNum starts with "Spam":
      set the icon of button btnNum to SpamIcon
    end if
  end for
end mouseUp

then I would click on that button and run the script. Then, once I have
satisfied myself that it has done what was needed, I'd delete the button.

If this was something that needed to run each time the application ran, I
would put the script in some other layer of the application, say, in the
card layer, in a named handler:

on setBtnStyle:
  for btnNum in 1 to the number of buttons:
    set the textsize of button btnNum to 9
    set the textstyle of button btnNum to bold,italic
    if the name of button btnNum starts with "Spam":
      set the icon of button btnNum to SpamIcon
    end if
  end for
end setBtnStyle


then call that handler on some event:

on openCard:
  setBtnStyle
end openCard

(In Hypercard, the UI model is of a Rolodex or set of cards, once card
displayed at a time in a window. Each card can contain widgets and
graphics. Displaying a card sends the openCard message to that card, which
runs whatever code is in the openCard handler. (Don't be put off by the
language of sending messages, that's identical to a method call.)

If this sounds kinda Javascript-y, it's because HC is one of the admitted
influences of early Javascript. If the business of sending messages sounds
kinda like Smalltalk, that's because HC was influenced by it. Apple history
buffs will see the influence of Alan Kay and Xerox PARC all over this...

Hypercard was not limited to manipulating the state of existing widgets. It
could programmatically create new ones. (Apple's Hypercard has a horrible
API for that where you literally gave a command to select a tool, then drag
from one point to another to create the widget. But later competing
products added more sensible commands for this.) If you had a complex
layout, you could code that part of the layout, but the point is that you
weren't forced to code everything.


[...]
> This doesn't have to be a dichotomy.

I didn't say it did :-)



-- 
Steven



More information about the Python-list mailing list