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.
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:
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: |
|
---|---|
Returns: | the values entered by the user in the order of 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: |
|
---|---|
Returns: | the values entered by the user in the order of fields |
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: |
|
---|
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.
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), ...].
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), ...].
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.
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.
Handle button presses: OK, Cancel and the callback buttons which are optional for text fields
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.
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.
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.
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.
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.
If the dialog box is resized, force a corresponding resize of the controls
Designed to be subclassed (eg by InfoDialog). By default simply returns the values unchanged.
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
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.
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.
Handle button presses: OK, Cancel and the callback buttons which are optional for text fields
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.
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.
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.
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.
If the dialog box is resized, force a corresponding resize of the controls
Called when the dialog is first initialised: estimate how wide the dialog should be according to the longest line of text
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
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 |
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 |
Base for dialog-related exceptions
See also