dialogs – Dialog boxes

Provides for simple dialog boxes, doing just enough to return input from the user using edit controls, dropdown lists and checkboxes. Most interaction is via the dialog(), progress_dialog() or info_dialog() functions. This example offers the user a drop-down list of installed Python directories, a text box to enter a size threshold and a checkbox to indicate whether to email the result:

from winsys import dialogs, registry
SIZE_THRESHOLD_MB = "100"
PYTHONREG = registry.registry (r"hklm\software\python\pythoncore")
version, size_threshold_mb, email_result = dialogs.dialog (
  "Find big files in Python",
  ("Version", [k.InstallPath.get_value ("") for k in PYTHONREG.keys ()]),
  ("Bigger than (Mb)", SIZE_THRESHOLD_MB),
  ("Email?", False)
)

All dialogs are resizable horizontally but not vertically. All edit boxes (fields with a default which is a string) accept file-drops, eg from Explorer.

The standard dialog (from dialog()) is modal and returns a tuple of values as soon as [Ok] is pressed or an empty list if [Cancel] is pressed. The progress dialog (from progress_dialog()) is also modal, but passes the tuple of values to a callback which yields update strings which are then displayed in the status box on the dialog. When the callback function completes, the dialog returns the tuple of values to the caller. info_dialog() is intended to be used for, eg, displaying a traceback or other bulky text for which a message box might be awkward. It displays multiline text in a readonly edit control which can be scrolled and select-copied.

Functions

dialog(title, *fields)

Shortcut function to populate and run a dialog, returning the button pressed and values saved. After the title, the function expects a series of 2-tuples where the first item is the field label and the second is the default value. This default value determines the type of ui element as follows:

  • list - a drop down list in the order given
  • bool - a checkbox
  • string - an edit control

A third item may be present in the tuple where the second item is a string. This is a callback function. If this is present and is not None, a small button will be added to the right of the corresponding edit control which, when pressed, will call the callback which must return a string to be inserted in the edit control, or None if no change is to be made. This is intended to throw up, eg, a file-browse dialog. A useful default is available as get_filename().

Parameters:
  • title – any string to use as the title of the dialog
  • fields – series of 2-tuples consisting of a name and a default value.
Returns:

the values entered by the user in the order of fields

progress_dialog(title, progress_callback, *fields)

Populate and run a dialog with a progress callback which yields messages. Fields are the same as for dialog() but the second parameter is a function which takes the value list as parameters and yields strings as updates. The strings will be displayed in a static control on the dialog while the [Ok] button is disabled until the callback completes, at which point the [Ok] button is enabled again and the tuple of values is returned to the caller.

Note

The progress callback runs inside a thread so any necessary thread-specific preparation must happen, eg invoking pythoncom.CoInitialize.

This example takes a directory from the user and finds the total size of each of its subdirectories, showing the name of each one as it is searched. Finally, it uses utils.size_as_mb() to display a human-redable version of each directory size:

from winsys import dialogs, fs, utils

sizes = {}
def sizer (root):
  for d in fs.dir (root).dirs ():
    yield d.name
    sizes[d] = sum (f.size for f in d.flat ())

dialogs.progress_dialog (
  "Sizer",
  sizer,
  ("Root", "c:/temp", dialogs.get_folder)
)

for d, size in sorted (sizes.items ()):
  print d.name, "=>", utils.size_as_mb (size)
Parameters:
  • title – any string to use as the title of the dialog
  • progress_callback – a function accepting values as per fields and yielding progress as strings
  • fields – series of 2-tuples consisting of a name and a default value
Returns:

the values entered by the user in the order of fields

info_dialog(title, text, hwnd=<Unset>)

A dialog with no fields which simply displays information in a read-only multiline edit box. The text can be arbitrarily big but the dialog will only adjust vertically up to a certain point. After that the user may scroll with the keyboard. The text can be selected and copied:

import os, sys
from winsys import dialogs
filepath = os.path.join (sys.prefix, "LICENSE.txt")
dialogs.info_dialog ("LICENSE.txt", open (filepath).read ())
Parameters:
  • title – any string to use as the title of the dialog
  • info – any (possibly multiline) string to display in the body of the dialog
  • parent_hwnd – optional window handle
get_filename(hwnd=None, start_folder=None)

Quick interface to the shell’s browse-for-folder dialog, optionally starting in a particular folder and allowing file and share selection.

Warning

At present this interacts badly with TortoiseHg, causing the interpreter to stack dump.

Classes

class BaseDialog(title, parent_hwnd=0)

Basic template for a dialog with one or more fields plus [Ok] and [Cancel] buttons. A simple spacing / sizing algorithm is used. Most of the work is done inside _get_dialog_template() which examines the incoming fields and tries to place them according to their various options.

Initialise the dialog with a title and a list of fields of the form [(label, default), ...].

class Dialog(title, fields, progress_callback=<Unset>, parent_hwnd=0)

A general-purpose dialog class for collecting arbitrary information in text strings and handing it back to the user. Only Ok & Cancel buttons are allowed, and all the fields are considered to be strings. The list of fields is of the form: [(label, default), ...] and the values are saved in the same order.

Initialise the dialog with a title and a list of fields of the form [(label, default), ...].

OnCallback(hwnd, field_id)

If the user pressed a callback button associated with a text field, find the field and call its callback with the dialog window and the field’s current value. If anything is returned, put that value back into the field.

OnCancel(hwnd)

If the user presses cancel check to see whether we’re running within a progress thread. If so, set the cancel event and wait for the thread to catch up. Either way, close the dialog with a cancelled state.

OnCommand(hwnd, msg, wparam, lparam)

Handle button presses: OK, Cancel and the callback buttons which are optional for text fields

OnInitDialog(hwnd, msg, wparam, lparam)

Attempt to position the dialog box more or less in the middle of its parent (possibly the desktop). Then force a resize of the dialog controls which should take into account the different label lengths and the dialog’s new size.

OnMinMaxInfo(hwnd, msg, wparam, lparam)

Prevent the dialog from resizing vertically by extracting the window’s current size and using the minmaxinfo message to set the maximum & minimum window heights to be its current height.

OnOk(hwnd)

When OK is pressed, if this isn’t a progress dialog then simply gather the results and return. If this is a progress dialog then start a thread to handle progress via the progress iterator.

OnProgressComplete(hwnd, msg, wparam, lparam)

Respond to the a message signalling that all processing is now complete by re-enabling the ok button, disabling cancel, and setting focus to the ok so a return or space will close the dialog.

OnProgressMessage(hwnd, msg, wparam, lparam)

Respond to a progress update from within the progress thread. LParam will be a pointer to a string containing a utf8-encoded string which is to be displayed in the dialog’s progress static.

OnSize(hwnd, msg, wparam, lparam)

If the dialog box is resized, force a corresponding resize of the controls

corners(l, t, r, b)

Designed to be subclassed (eg by InfoDialog). By default simply returns the values unchanged.

run()

The heart of the dialog box functionality. The call to DialogBoxIndirect kicks off the dialog’s message loop, finally returning via the EndDialog call in OnCommand

class InfoDialog(title, info, parent_hwnd=<Unset>)
OnCallback(hwnd, field_id)

If the user pressed a callback button associated with a text field, find the field and call its callback with the dialog window and the field’s current value. If anything is returned, put that value back into the field.

OnCancel(hwnd)

If the user presses cancel check to see whether we’re running within a progress thread. If so, set the cancel event and wait for the thread to catch up. Either way, close the dialog with a cancelled state.

OnCommand(hwnd, msg, wparam, lparam)

Handle button presses: OK, Cancel and the callback buttons which are optional for text fields

OnInitDialog(hwnd, msg, wparam, lparam)

Attempt to position the dialog box more or less in the middle of its parent (possibly the desktop). Then force a resize of the dialog controls which should take into account the different label lengths and the dialog’s new size.

OnMinMaxInfo(hwnd, msg, wparam, lparam)

Prevent the dialog from resizing vertically by extracting the window’s current size and using the minmaxinfo message to set the maximum & minimum window heights to be its current height.

OnOk(hwnd)
OnProgressComplete(hwnd, msg, wparam, lparam)

Respond to the a message signalling that all processing is now complete by re-enabling the ok button, disabling cancel, and setting focus to the ok so a return or space will close the dialog.

OnProgressMessage(hwnd, msg, wparam, lparam)

Respond to a progress update from within the progress thread. LParam will be a pointer to a string containing a utf8-encoded string which is to be displayed in the dialog’s progress static.

OnSize(hwnd, msg, wparam, lparam)

If the dialog box is resized, force a corresponding resize of the controls

corners(l, t, r, b)

Called when the dialog is first initialised: estimate how wide the dialog should be according to the longest line of text

run()

The heart of the dialog box functionality. The call to DialogBoxIndirect kicks off the dialog’s message loop, finally returning via the EndDialog call in OnCommand

Constants

BIF

Styles for browsing for a folder

Name Val Win32
RETURNONLYFSDIRS 1 BIF_RETURNONLYFSDIRS
NOTRANSLATETARGETS 1024 BIF_NOTRANSLATETARGETS
BROWSEINCLUDEURLS 128 BIF_BROWSEINCLUDEURLS
EDITBOX 16 BIF_EDITBOX
BROWSEINCLUDEFILES 16384 BIF_BROWSEINCLUDEFILES
DONTGOBELOWDOMAIN 2 BIF_DONTGOBELOWDOMAIN
UAHINT 256 BIF_UAHINT
VALIDATE 32 BIF_VALIDATE
SHAREABLE 32768 BIF_SHAREABLE
STATUSTEXT 4 BIF_STATUSTEXT
BROWSEFORCOMPUTER 4096 BIF_BROWSEFORCOMPUTER
NONEWFOLDERBUTTON 512 BIF_NONEWFOLDERBUTTON
NEWDIALOGSTYLE 64 BIF_NEWDIALOGSTYLE
RETURNFSANCESTORS 8 BIF_RETURNFSANCESTORS
USENEWUI 80 USENEWUI
BROWSEFORPRINTER 8192 BIF_BROWSEFORPRINTER
BFFM

Part of the browse-for-folder shell mechanism

Name Val Win32
INITIALIZED 1 BFFM_INITIALIZED
SETSTATUSTEXTA 1124 BFFM_SETSTATUSTEXTA
SETSTATUSTEXT 1124 BFFM_SETSTATUSTEXTA
ENABLEOK 1125 BFFM_ENABLEOK
SETSELECTION 1126 BFFM_SETSELECTIONA
SETSELECTIONA 1126 BFFM_SETSELECTIONA
SETSELECTIONW 1127 BFFM_SETSELECTIONW
SETSTATUSTEXTW 1128 BFFM_SETSTATUSTEXTW
SELCHANGED 2 BFFM_SELCHANGED
VALIDATEFAILEDA 3 BFFM_VALIDATEFAILEDA
VALIDATEFAILED 3 BFFM_VALIDATEFAILEDA
VALIDATEFAILEDW 4 BFFM_VALIDATEFAILEDW

Exceptions

exception x_dialogs(errno=None, errctx=None, errmsg=None)

Base for dialog-related exceptions

References

See also

Using the dialogs module
Cookbook examples of using the accounts module

Table Of Contents

Previous topic

accounts – Users, Groups, SIDs &c.

Next topic

event_logs – Event Logs

This Page