Read Programming Python Online

Authors: Mark Lutz

Tags: #COMPUTERS / Programming Languages / Python

Programming Python (89 page)

BOOK: Programming Python
13.66Mb size Format: txt, pdf, ePub
ads
PyEdit: A Text Editor Program/Object

In the last few decades,
I’ve typed text into a lot of programs. Most were closed
systems (I had to live with whatever decisions their designers made), and
many ran on only one platform. The PyEdit program presented in this
section does better on both counts: according to its own Tools/Info
option, PyEdit implements a full-featured, graphical text editor program
in a total of
1,133
new lines of
portable Python code, including whitespace and comments, divided between
1,088 lines in the main file and 45 lines of configuration module settings
(at release, at least—final sizes may vary slightly in future revisions).
Despite its relatively modest size, by systems programming standards,
PyEdit
is sufficiently powerful and
robust to have served as the primary tool for coding most of the examples
in this book.

PyEdit supports all the usual mouse and keyboard text-editing
operations: cut and paste, search and replace, open and save, undo and
redo, and so on. But really, PyEdit is a bit more than just another text
editor—it is designed to be used as both a program and a library
component, and it can be run in a variety of roles:

Standalone mode

As a standalone text-editor program, with or without the name
of a file to be edited passed in on the command line. In this mode,
PyEdit is roughly like other text-editing utility programs (e.g.,
Notepad on Windows), but it also provides advanced functions such as
running Python program code being edited, changing fonts and colors,
“grep” threaded external file search, a multiple window interface,
and so on. More important, because it is coded in Python, PyEdit is
easy to customize, and it runs portably on Windows, X Windows, and
Macintosh.

Pop-up mode

Within a new pop-up window, allowing an arbitrary number of
copies to appear as pop ups at once in a program. Because state
information is stored in class instance attributes, each PyEdit
object created operates independently. In this mode and the next,
PyEdit serves as a library object for use in other scripts, not as a
canned application. For example,
Chapter 14
’s PyMailGUI employs PyEdit in
pop-up mode to view email attachments and raw text, and both
PyMailGUI and the preceding chapter’s PyDemos display source code
files this way.

Embedded mode

As an attached component, to provide a text-editing widget for
other GUIs. When attached, PyEdit uses a frame-based menu and can
optionally disable some of its menu options for an embedded role.
For instance, PyView (later in this chapter) uses PyEdit in embedded
mode this way to serve as a note editor for photos, and PyMailGUI
(in
Chapter 14
) attaches it to get an
email text editor for free.

While such mixed-mode behavior may sound complicated to implement,
most of
PyEdit
’s modes are a natural
byproduct of coding GUIs with the class-based techniques we’ve seen in the
last four chapters.

Running PyEdit

PyEdit sports
lots of features, and the best way to learn how it works
is to test-drive it for yourself—you can run it by starting the main
file
textEditor.py
, by running files
textEditorNoConsole.pyw
or
pyedit.pyw
to suppress a console window on
Windows, or from the PyDemos and PyGadgets launcher bars described at
the end of
Chapter 10
(the launchers
themselves live in the top level of the book examples directory tree).
To give you a sampling of PyEdit’s interfaces,
Figure 11-1
shows the main
window’s
default appearance
running in Windows 7, after opening PyEdit’s own source code
file.

Figure 11-1. PyEdit main window, editing itself

The main part of this window is a
Text
widget object, and if you read
Chapter 9
’s coverage of this widget,
PyEdit text-editing operations will be familiar. It uses text marks,
tags, and indexes, and it implements cut-and-paste operations with the
system clipboard so that PyEdit can paste data to and from other
applications, even after an application of origin is closed. Both
vertical and horizontal scroll bars are cross-linked to the
Text
widget, to support movement through
arbitrary files.

Menus and toolbars

If PyEdit’s menu
and toolbars look familiar, they should—PyEdit builds
the main window with minimal code and appropriate clipping and
expansion policies by mixing in the
GuiMaker
class we coded in the prior chapter
(
Example 10-3
). The
toolbar at the bottom contains shortcut buttons for operations I tend
to use most often; if my preferences don’t match yours, simply change
the toolbar list in the source code to show the buttons you want (this
is Python, after all).

As usual for tkinter menus, shortcut key combinations can be
used to invoke menu options quickly, too—press Alt plus all the
underlined keys of entries along the path to the desired action. Menus
can also be torn off at their dashed line to provide quick access to
menu options in new top-level windows (handy for options without
toolbar buttons).

Dialogs

PyEdit pops
up a variety of modal and nonmodal dialogs, both
standard and custom.
Figure 11-2
shows the custom
and nonmodal change, font, and grep dialogs, along with a standard
dialog used to display file statistics (the final line count may vary,
as I tend to tweak code and comments right up until final
draft).

Figure 11-2. PyEdit with colors, a font, and a few pop ups

The main window in
Figure 11-2
has been given
new foreground and background colors (with the standard color
selection dialog), and a new text font has been selected from either
the font dialog or a canned list in the script that users can change
to suit their preferences (this is Python, after all). Other toolbar
and menu operations generally use popped-up standard dialogs, with a
few new twists. For instance, the standard file open and save
selection dialogs in PyEdit use object-based interfaces to remember
the last directory visited, so you don’t have to navigate there every
time.

Running program code

One of the
more unique features of PyEdit is that it can actually
run Python program code that you are editing. This isn’t as hard as it
may sound either—because Python provides built-ins for compiling and
running code strings and for launching programs, PyEdit simply has to
make the right calls for this to work. For example, it’s easy to code
a simple-minded Python interpreter in Python, using code like the
following (see file
simpleShell.py
in the PyEdit’s directory if
you wish to experiment with this), though you need a bit more to
handle multiple-line statements and expression result displays:

# read and run Python statement strings: like PyEdit's run code menu option
namespace = {}
while True:
try:
line = input('>>> ') # single-line statements only
except EOFError:
break
else:
exec(line, namespace) # or eval() and print result

Depending on the user’s preference, PyEdit either does something
similar to this to run code fetched from the text widget or uses the
launchmodes
module we wrote at the
end of
Chapter 5
to run the code’s file
as an independent program. There are a variety of options in both
schemes that you can customize as you like (this is Python, after
all). See the
onRunCode
method for
details or simply edit and run some Python code in PyEdit on your own
to experiment. When edited code is run in nonfile mode, you can view
its printed output in PyEdit’s console window. As we footnoted about
eval
and
exec
in
Chapter 9
, also make sure you trust the
source of code you run this way; it has all permissions that the
Python process does.

Multiple windows

PyEdit not
only pops up multiple special-purpose windows, it also
allows multiple edit windows to be open concurrently, in either the
same process or as independent programs. For illustration,
Figure 11-3
shows three
independently started instances of PyEdit, resized and running with a
variety of color schemes and fonts. Since these are separate programs,
closing any of these does not close the others. This figure also
captures PyEdit torn-off menus at the bottom and the PyEdit help pop
up on the right. The edit windows’ backgrounds are shades of green,
red, and blue; use the Tools menu’s Pick options to set colors as you
like.

Figure 11-3. Multiple PyEdit sessions at work

Since these three PyEdit sessions are editing Python
source-coded text, you can run their contents with the Run Code option
in the Tools pull-down menu. Code run from files is spawned
independently; the standard streams of code run not from a file (i.e.,
fetched from the text widget itself) are mapped to the PyEdit
session’s console window. This isn’t an IDE by any means; it’s just
something I added because I found it to be useful. It’s nice to run
code you’re editing without fishing through directories.

To run multiple edit windows in the same process, use the Tools
menu’s Clone option to open a new empty window without erasing the
content of another.
Figure 11-4
shows the
single-process scene with a window and its clone, along with pop-ups
related to the Search menu’s Grep option, described in the next
section—a tool that walks directory trees in parallel threads,
collecting files of matching names that contain a search string, and
opening them on request. In
Figure 11-4
, Grep has
produced an input dialog, a matches list, and a new PyEdit window
positioned at a match after a double-click in the list box.

Figure 11-4. Multiple PyEdit windows in a single process

Another pop up appears while a Grep search is in progress, but
the GUI remains fully active; in fact, you can launch new Greps while
others are in progress. Notice how the Grep dialog also allows input
of a Unicode encoding, used to decode file content in all text files
visited during the tree search; I’ll describe how this works in the
changes section ahead, but in most cases, you can accept the prefilled
platform default encoding.

For more fun, use this dialog to run a Grep in directory
C:\Python31
for all
*.py
files that contain string
%
—a quick look at how common the original
string formatting expression is, even in Python 3.1’s own library
code. Though not all
%
are related
to string formatting, most appear to be. Per a message printed to
standard output on Grep thread exit, the string
'%'
(which includes substitution targets)
occurs
6,050
times, and the string
' % '
(with surrounding spaces to better
narrow in on operator appearances) appears
3,741
times, including 130 in the installed PIL extension—not exactly an
obscure language tool! Here are the messages printed to standard
output during this search; matches appear in a list box window:

...errors may vary per encoding type...
Unicode error in: C:\Python31\Lib\lib2to3\tests\data\different_encoding.py
Unicode error in: C:\Python31\Lib\test\test_doctest2.py
Unicode error in: C:\Python31\Lib\test\test_tokenize.py
Matches for % : 3741

PyEdit generates additional pop-up windows—including transient
Goto and Find dialogs, color selection dialogs, dialogs that appear to
collect arguments and modes for Run Code, and dialogs that prompt for
entry of Unicode encoding names on file Open and Save if PyEdit is
configured to ask (more on this ahead). In the interest of space, I’ll
leave most other such behavior for you to witness live.

Prominently new in this edition, though, and subject to user
configurations, PyEdit may ask for a file’s Unicode encoding name when
opening a file, saving a new file begun from scratch, or running a
Save As operation. For example,
Figure 11-5
captures the
scene after I’ve opened a file encoded in a Chinese character set
scheme and pressed Open again to open a new file encoded in a Russian
encoding. The encoding name input dialog shown in the figure appears
immediately after the standard file selection dialog is dismissed, and
it is prefilled with the default encoding choice configured (an
explicit setting or the platform’s default). The displayed default can
be accepted in most cases, unless you know the file’s encoding
differs.

Figure 11-5. PyEdit displaying Chinese text and prompting for encoding on
Open

In general, PyEdit supports any Unicode character set that
Python and tkinter do, for opens, display, and saves. The text in
Figure 11-5
, for
instance, was encoding in a specific Chinese encoding in the file it
came from (“gb2321” for file
email-part--gb2312
). An alternative UTF-8
encoding of this text is available in the same directory (file
email-part--gb2312--utf8
) which
works per the default Windows encoding in
PyEdit
and Notepad, but the specific
Chinese encoding file requires the explicitly
entered
encoding name to display
properly in PyEdit (and won’t display correctly at all in
Notepad
).

After I enter the encoding name for the selected file (“koi8-r”
for the file selected to open) in the input dialog of
Figure 11-5
, PyEdit decodes
and pops up the text in its display.
Figure 11-6
show the scene
after this file has been opened and I’ve selected the Save As option
in this window—immediately after a file selection dialog is dismissed,
another encoding input dialog is presented for the new file, prefilled
with the known encoding from the last Open or Save. As configured,
Save reuses the known encoding automatically to write to the file
again, but SaveAs always asks to allow for a new one, before trying
defaults. Again, I’ll say more on the Unicode/Internationalization
policies of PyEdit in the next section, when we discuss version 2.1
changes; in short, because user preferences can’t be predicted, a
variety of policies may be selected by
configuration
.

Figure 11-6. PyEdit displaying Russian text and prompting for encoding on
Save As

Finally, when it’s time to shut down for the day, PyEdit does
what it can to avoid losing changes not saved. When a
Quit
is requested for any edit window, PyEdit
checks for changes and verifies the operation in a dialog if the
window’s text has been modified and not saved. Because there may be
multiple edit windows in the same process, when a Quit is requested in
a main window, PyEdit also checks for changes in all other windows
still open, and verifies exit if any have been altered—otherwise the
Quit would close every window silently. Quits in pop-up edit windows
destroy that window only, so no cross-process check is made. If no
changes have been made, Quit requests in the GUI close windows and
programs silently. Other operations verify changes in similar
ways.

BOOK: Programming Python
13.66Mb size Format: txt, pdf, ePub
ads

Other books

The House Next Door by P. J. Night
The Ghost of Christmas Past by Sally Quilford
The Life of an Unknown Man by Andreï Makine
Live-In Position by Tice, V.S.
Daffodils in March by Clare Revell


readsbookonline.com Copyright 2016 - 2024