Dialog
class overview¶
Initializing a Dialog
instance¶
Since all widgets in pythondialog are implemented as methods of the
Dialog
class, a pythondialog-based application usually starts by
creating a Dialog
instance.
- class dialog.Dialog(dialog='dialog', DIALOGRC=None, compat='dialog', use_stdout=None, *, autowidgetsize=False, pass_args_via_file=None)[source]¶
Class providing bindings for dialog-compatible programs.
This class allows you to invoke dialog or a compatible program in a pythonic way to quickly and easily build simple but nice text interfaces.
An application typically creates one instance of the
Dialog
class and uses it for all its widgets, but it is possible to concurrently use several instances of this class with different parameters (such as the background title) if you have a need for this.- __init__(dialog='dialog', DIALOGRC=None, compat='dialog', use_stdout=None, *, autowidgetsize=False, pass_args_via_file=None)[source]¶
Constructor for
Dialog
instances.- Parameters
dialog (str) – name of (or path to) the dialog-like program to use. If it contains a slash (
/
), it must be a relative or absolute path to a file that has read and execute permissions, and is used as is; otherwise, it is looked for according to the contents of thePATH
environment variable, which defaults to/bin:/usr/bin
if unset. In case you decide to use a relative path containing a/
, be very careful about the current directory at the time the Dialog instance is created. Indeed, if for instance you use"foobar/dialog"
and your program creates the Dialog instance at a time where the current directory is for instance/tmp
, then/tmp/foobar/dialog
will be run, which could be risky. If you don’t understand this, stay with the default, use a value containing no/
, or use an absolute path (i.e., one starting with a/
).DIALOGRC (str) – string to pass to the dialog-like program as the
DIALOGRC
environment variable, orNone
if no modification to the environment regarding this variable should be done in the call to the dialog-like programuse_stdout (bool) – read dialog’s standard output stream instead of its standard error stream in order to get most “results” (user-supplied strings, selected items, etc.; basically, everything except the exit status). This is for compatibility with Xdialog and should only be used if you have a good reason to do so.
autowidgetsize (bool) – whether to enable autowidgetsize mode. When enabled, all pythondialog widget-producing methods will behave as if
width=0
,height=0
, etc. had been passed, except where these parameters are explicitely specified with different values. This has the effect that, by default, the dialog backend will automatically compute a suitable size for the widgets. More details about this option are given below.pass_args_via_file (bool or
None
) – whether to use the--file
option with a temporary file in order to pass arguments to the dialog backend, instead of including them directly into the argument list; using--file
has the advantage of not exposing the “real” arguments to other users through the process table. With the default value (None
), the option is enabled if the dialog version is recent enough to offer a reliable--file
implementation (i.e., 1.2-20150513 or later).
- Returns
a
Dialog
instance
The officially supported dialog-like program in pythondialog is the well-known dialog program written in C, based on the ncurses library.
If you want to use a different program such as Xdialog, you should indicate the executable file name with the dialog argument and the compatibility type that you think it conforms to with the compat argument. Currently, compat can be either
"dialog"
(for dialog; this is the default) or"Xdialog"
(for, well, Xdialog).The compat argument allows me to cope with minor differences in behaviour between the various programs implementing the dialog interface (not the text or graphical interface, I mean the API). However, having to support various APIs simultaneously is ugly and I would really prefer you to report bugs to the relevant maintainers when you find incompatibilities with dialog. This is for the benefit of pretty much everyone that relies on the dialog interface.
Notable exceptions:
New in version 3.1: Support for the autowidgetsize parameter.
New in version 3.3: Support for the pass_args_via_file parameter.
About the autowidgetsize option
The autowidgetsize option should be convenient in situations where figuring out suitable widget size parameters is a burden, for instance when developing little scripts that don’t need too much visual polishing, when a widget is used to display data, the size of which is not easily predictable, or simply when one doesn’t want to hardcode the widget size.
This option is implemented in the following way: for a given size parameter
(for instance, width) of a given widget, the default value in the
widget-producing method is now None
if it previously had a non-zero
default. At runtime, if the value seen by the widget-producing method is not
None
, it is used as is; on the contrary, if that value is None
, it is
automatically replaced with:
0
if theDialog
instance has been initialized with autowidgetsize set toTrue
;the old default otherwise, in order to preserve backward-comptability.
Note
the autowidgetsize option is currently marked as experimental, please give some feedback;
you may encounter questionable results if you only set one of the width and height parameters to
0
for a given widget (seen in dialog 1.2-20140219).
Warning
You should not explicitly pass None
for a size parameter such as width
or height. If you want a fixed size, specify it directly (as an int);
otherwise, either use the autowidgetsize option or set the parameter to
0
(e.g., width=0
).
Passing dialog “common options”¶
Every widget method has a **kwargs argument allowing you to pass
common options (see the dialog(1)
manual page) to dialog for this widget call. For instance, if d
is a Dialog
instance, you can write:
d.checklist(args, ..., title="A Great Title", no_shadow=True)
The no_shadow option is worth looking at:
It is an option that takes no argument as far as dialog is concerned (unlike the
--title
option, for instance). When you list it as a keyword argument, the option is really passed to dialog only if the value you gave it evaluates toTrue
in a boolean context. For instance,no_shadow=True
will cause--no-shadow
to be passed to dialog whereasno_shadow=False
will cause this option not to be passed to dialog at all.It is an option that has a hyphen (
-
) in its name, which you must change into an underscore (_
) to pass it as a Python keyword argument. Therefore,--no-shadow
is passed by giving ano_shadow=True
keyword argument toDialog
methods (the leading two dashes are also consistently removed).
Note
When Dialog.__init__()
is called with
pass_args_via_file=True
(or without any explicit setting for this
option, and the pythondialog as well as dialog versions are
recent enough so that the option is enabled by default), then the options
are not directly passed to dialog. Instead, all options are
written to a temporary file which dialog is pointed to via
--file
. This ensures better confidentiality with respect to other
users of the same computer.
New in version 2.14: Support for the default_button and no_tags common options.
New in version 3.0: Proper support for the extra_button, item_help and help_status common options.
Return value of widget-producing methods¶
Most Dialog
methods that create a widget (actually: all methods that
supervise the exit of a widget) return a value which fits into one of these
categories:
The return value is a Dialog exit code (see below).
The return value is a sequence whose first element is a Dialog exit code (the rest of the sequence being related to what the user entered in the widget).
For instance, Dialog.yesno()
returns a single Dialog exit code that will
typically be Dialog.OK
or Dialog.CANCEL
, depending on the
button chosen by the user. However, Dialog.checklist()
returns a tuple
of the form (code, [tag, ...])
whose first element is a Dialog
exit code and second element lists all tags for the entries selected by the
user.
“Dialog exit code” (high-level)¶
A Dialog exit code, or high-level exit code, is a string
indicating how/why a widget-producing method ended. Most widgets return one of
the standard Dialog exit codes: "ok"
,
"cancel"
, "esc"
, "help"
, "extra"
and "timeout"
,
respectively available as Dialog.OK
, Dialog.CANCEL
,
Dialog.ESC
, Dialog.HELP
, Dialog.EXTRA
and
Dialog.TIMEOUT
, i.e., attributes of the Dialog
class.
However, some widgets may return additional, non-standard exit codes; for
instance, the inputmenu()
widget may return "accepted"
or
"renamed"
in addition to the standard Dialog exit codes.
When getting a Dialog exit code from a widget-producing method, user code
should compare it with Dialog.OK
and friends (or equivalently, with
"ok"
and friends) using the ==
operator. This allows to easily replace
Dialog.OK
and friends with objects that compare the same with "ok"
and u"ok"
in Python 2, for instance.
The following attributes of the Dialog
class hold the standard
Dialog exit codes:
- Dialog.OK = 'ok'¶
Dialog exit code corresponding to the
DIALOG_OK
dialog exit status
- Dialog.CANCEL = 'cancel'¶
Dialog exit code corresponding to the
DIALOG_CANCEL
dialog exit status
- Dialog.ESC = 'esc'¶
Dialog exit code corresponding to the
DIALOG_ESC
dialog exit status
- Dialog.EXTRA = 'extra'¶
Dialog exit code corresponding to the
DIALOG_EXTRA
dialog exit status
- Dialog.HELP = 'help'¶
Dialog exit code corresponding to the
DIALOG_HELP
andDIALOG_ITEM_HELP
dialog exit statuses
- Dialog.TIMEOUT = 'timeout'¶
Dialog exit code corresponding to the
DIALOG_TIMEOUT
dialog exit status
The following attributes are obsolete and should not be used in pythondialog 3.0 and later:
- Dialog.DIALOG_CANCEL¶
Obsolete property superseded by
Dialog.CANCEL
since version 3.0
- Dialog.DIALOG_ESC¶
Obsolete property superseded by
Dialog.ESC
since version 3.0
- Dialog.DIALOG_EXTRA¶
Obsolete property superseded by
Dialog.EXTRA
since version 3.0
- Dialog.DIALOG_HELP¶
Obsolete property superseded by
Dialog.HELP
since version 3.0
- Dialog.DIALOG_ITEM_HELP¶
Obsolete property superseded by
Dialog.HELP
since version 3.0
“dialog exit status” (low-level)¶
When returning from a widget call, the Dialog exit code is normally
derived by pythondialog from an integer called dialog exit status, or
low-level exit code. This integer is returned by the dialog
backend upon exit. The different possible values for the dialog exit status
are referred to as DIALOG_OK
, DIALOG_CANCEL
, DIALOG_ESC
,
DIALOG_ERROR
, DIALOG_EXTRA
, DIALOG_HELP
, DIALOG_ITEM_HELP
and DIALOG_TIMEOUT
in the dialog(1) manual page.
Note
DIALOG_HELP
andDIALOG_ITEM_HELP
both map toDialog.HELP
in pythondialog, because they both correspond to the same user action and the difference brings no information that the caller does not already have;DIALOG_ERROR
has no counterpart as aDialog
attribute, because it is automatically translated into aDialogError
exception when received.
In pythondialog 2.x, the low-level exit codes were available as the
DIALOG_OK
, DIALOG_CANCEL
, etc. attributes of Dialog
instances. For compatibility, the Dialog
class has attributes of the
same names that are mapped to Dialog.OK
, Dialog.CANCEL
, etc.,
but their use is deprecated as of pythondialog 3.0.
Providing on-line help facilities¶
With most dialog widgets, it is possible to provide online help to
the final user. At the time of this writing (October 2014), there are three
main options governing these help facilities in the dialog backend:
--help-button
, --item-help
and --help-status
.
Since dialog 1.2-20130902, there is also --help-tags
that
modifies the way --item-help
works. As explained previously
(Passing dialog “common options”), in order to use these options in
pythondialog, you can pass the help_button, item_help, help_status and
help_tags keyword arguments to Dialog
widget-producing methods.
Providing inline per-item help¶
In addition to, or instead of the Help button, you can provide
item-specific help that is normally displayed at the bottom of the
widget. This can be done by passing the item_help=True
keyword argument to
the widget-producing method and by including the item-specific help strings in
the appropriate argument.
For widgets where item-specific help makes sense (i.e., there are several
elements that can be highlighted), there is usually a parameter, often called
elements, choices, nodes…, that must be provided as an iterable
describing the various lines/items/nodes/… that can be highlighted in the
widget. When item_help=True
is passed, every element of this iterable must
be completed with a string which is the item-help string of the element
(using dialog(1) terminology). For instance, the following call
with no inline per-item help support:
code, t = d.checklist(
"<text>", height=0, width=0, list_height=0,
choices=[ ("Tag 1", "Item 1", False),
("Tag 2", "Item 2", True),
("Tag 3", "Item 3", True) ],
help_button=True)
can be altered this way to provide inline item-specific help:
code, t = d.checklist(
"<text>", height=0, width=0, list_height=0,
choices=[ ("Tag 1", "Item 1", False, "Help 1"),
("Tag 2", "Item 2", True, "Help 2"),
("Tag 3", "Item 3", True, "Help 3") ],
help_button=True, item_help=True, help_tags=True)
With this modification, the item-help string for the highlighted item is displayed in the bottom line of the screen and updated as the user highlights other items.
If you don’t want a Help button, just use item_help=True
without help_button=True
(help_tags doesn’t matter in this case). Then,
you have the inline help at the bottom of the screen, and the following
discussion about the return value can be ignored.
If the user chooses the Help button, code will be equal to
Dialog.HELP
("help"
) and t will contain the tag string
corresponding to the highlighted item when the Help button was
pressed ("Tag 1/2/3"
in the example). This is because of the help_tags
option; without it (or with help_tags=False
), t would have contained the
item-help string of the highlighted choice ("Help 1/2/3"
in the
example).
If you remember what was said earlier, if item_help=True
had not been used
in the previous example, t would still contain the tag of the highlighted
choice if the user closed the widget with the Help button. This is
the same as when using item_help=True
in combination with
help_tags=True
; however, you would get the item-help string
instead if help_tags were False
(which is the default, as in the
dialog backend, and in order to preserve compatibility with the
Dialog.menu()
implementation that is several years old).
Therefore, I recommend for consistency to use help_tags=True
whenever
possible when specifying item_help=True
. This makes "--help-tags"
a
good candidate for use with Dialog.add_persistent_args()
to avoid
repeating it over and over. However, there are two cases where
help_tags=True
cannot be used:
when the version of the dialog backend is lower than 1.2-20130902 (the
--help-tags
option was added in this version);when using empty or otherwise identical tags for presentation purposes (unless you don’t need to tell which element was highlighted when the Help button was pressed, in which case it doesn’t matter to be unable to discriminate between the tags).
Checking the versions of pythondialog and its backend¶
Version of pythondialog¶
- class dialog.VersionInfo(major, minor, micro, releasesuffix)[source]¶
Class used to represent the version of pythondialog.
This class is based on
collections.namedtuple()
and has the following field names:major
,minor
,micro
,releasesuffix
.New in version 2.14.
- dialog.version_info¶
Version of pythondialog as a
VersionInfo
instance.New in version 2.14.
- dialog.__version__¶
Version of pythondialog as a string.
New in version 2.12.
Version of the backend¶
The Dialog
constructor retrieves the version string of the
dialog backend and stores it as an instance of a
BackendVersion
subclass into the
Dialog.cached_backend_version
attribute. This allows doing things such
as (d being a Dialog
instance):
if d.compat == "dialog" and \
d.cached_backend_version >= DialogBackendVersion("1.2-20130902"):
...
in a reliable way, allowing to fix the parsing and comparison algorithms right
in the appropriate BackendVersion
subclass, should the
dialog-like backend versioning scheme change in unforeseen ways.
As Xdialog seems to be dead and not to support
--print-version
, the Dialog.cached_backend_version
attribute
is set to None
in Xdialog-compatibility mode (2013-09-12).
Should this ever change, one should define an XDialogBackendVersion
class to handle the particularities of the Xdialog versioning
scheme.
- Dialog.cached_backend_version¶
Instance of a
BackendVersion
subclass; it is initialized by theDialog
constructor and used to store the backend version, avoiding the need to repeatedly calldialog --print-version
or a similar command, depending on the backend.When using the dialog backend,
Dialog.cached_backend_version
is aDialogBackendVersion
instance.
- Dialog.backend_version()[source]¶
Get the version of the dialog-like program (backend).
If the version of the dialog-like program can be retrieved, return it as a string; otherwise, raise
UnableToRetrieveBackendVersion
.This version is not to be confused with the pythondialog version.
In most cases, you should rather use the
cached_backend_version
attribute ofDialog
instances, because:it avoids calling the backend every time one needs the version;
it is a
BackendVersion
instance (or instance of a subclass) that allows easy and reliable comparisons between versions;the version string corresponding to a
BackendVersion
instance (or instance of a subclass) can be obtained withstr()
.
Notable exceptions:
any exception raised by
Dialog._perform()
New in version 2.12.
Changed in version 2.14: Raise
UnableToRetrieveBackendVersion
instead of returningNone
when the version of the dialog-like program can’t be retrieved.
Enabling debug facilities¶
- Dialog.setup_debug(enable, file=None, always_flush=False, *, expand_file_opt=False)[source]¶
Setup the debugging parameters.
- Parameters
enable (bool) – whether to enable or disable debugging
file (file) – where to write debugging information
always_flush (bool) – whether to call
file.flush()
after each command writtenexpand_file_opt (bool) – when
Dialog.__init__()
has been called withpass_args_via_file=True
, this option causes the--file
options that would normally be written to file to be expanded, yielding a similar result to what would be obtained withpass_args_via_file=False
(but contrary topass_args_via_file=False
, this only affects file, not the actual dialog calls). This is useful, for instance, for copying some of the dialog commands into a shell.
When enable is true, all dialog commands are written to file using POSIX shell syntax. In this case, you’ll probably want to use either
expand_file_opt=True
in this method orpass_args_via_file=False
inDialog.__init__()
, otherwise you’ll mostly see dialog calls containing only one--file
option followed by a path to a temporary file.New in version 2.12.
New in version 3.3: Support for the expand_file_opt parameter.
Miscellaneous methods¶
- Dialog.add_persistent_args(args)[source]¶
Add arguments to use for every subsequent dialog call.
This method cannot guess which elements of args are dialog options (such as
--title
) and which are not (for instance, you might want to use--title
or even--
as an argument to a dialog option). Therefore, this method does not perform any kind of dash escaping; you have to do it yourself.dash_escape()
anddash_escape_nf()
may be useful for this purpose.
Note
When Dialog.__init__()
is called with
pass_args_via_file=True
(or without any explicit setting for this
option, and the pythondialog as well as dialog versions are
recent enough so that the option is enabled by default), then the arguments
are not directly passed to dialog. Instead, all arguments are
written to a temporary file which dialog is pointed to via
--file
. This ensures better confidentiality with respect to other
users of the same computer.
- classmethod Dialog.dash_escape(args)[source]¶
Escape all elements of args that need escaping for dialog.
args may be any sequence and is not modified by this method. Return a new list where every element that needs escaping has been escaped.
An element needs escaping when it starts with two ASCII hyphens (
--
). Escaping consists in prepending an element composed of two ASCII hyphens, i.e., the string'--'
.All high-level
Dialog
methods automatically perform dash escaping where appropriate. In particular, this is the case for every method that provides a widget:yesno()
,msgbox()
, etc. You only need to do it yourself when calling a low-level method such asadd_persistent_args()
.New in version 2.12.
- classmethod Dialog.dash_escape_nf(args)[source]¶
Escape all elements of args that need escaping, except the first one.
See
dash_escape()
for details. Return a new list.All high-level
Dialog
methods automatically perform dash escaping where appropriate. In particular, this is the case for every method that provides a widget:yesno()
,msgbox()
, etc. You only need to do it yourself when calling a low-level method such asadd_persistent_args()
.New in version 2.12.
A contrived example using these methods could be the following, which sets a
weird background title starting with two dashes (--My little program
) for
the life duration of a Dialog
instance d:
d.add_persistent_args(d.dash_escape_nf(
["--backtitle", "--My little program"]))
or, equivalently:
d.add_persistent_args(["--backtitle"]
+ d.dash_escape(["--My little program"]))