# `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)

  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)

    Constructor for `Dialog` instances.

    Parameters:

    - dialog (str) – name of (or path to) the dialog-like program to use; if it contains a `'/'`, it is assumed to be a path and is used as is; otherwise, it is looked for according to the contents of the `PATH` environment variable, which defaults to `":/bin:/usr/bin"` if unset.
    - DIALOGRC (str) – string to pass to the dialog-like program as the `DIALOGRC` environment variable, or `None` if no modification to the environment regarding this variable should be done in the call to the dialog-like program
    - compat (str) – compatibility mode (see below)
    - use_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:

    > - `ExecutableNotFound`
    > - `PythonDialogOSError`
    > - `UnableToRetrieveBackendVersion`
    > - `UnableToParseBackendVersion`

    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 the `Dialog` instance has been initialized with autowidgetsize set to `True`;
> - 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:

> 1. 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 to `True` in a boolean context. For instance, `no_shadow=True` will cause `--no-shadow` to be passed to dialog whereas `no_shadow=False` will cause this option not to be passed to dialog at all.
> 2. 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 a `no_shadow=True` keyword argument to `Dialog` 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:

> 1. The return value is a Dialog exit code (see below).
> 2. 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"` and `"extra"`, respectively available as `Dialog.OK`, `Dialog.CANCEL`, `Dialog.ESC`, `Dialog.HELP` and `Dialog.EXTRA`, 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` and `DIALOG_ITEM_HELP` dialog exit statuses

The following attributes are obsolete and should not be used in pythondialog 3.0 and later:

`Dialog.``DIALOG_OK`

  Obsolete property superseded by `Dialog.OK` since version 3.0

`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` and `DIALOG_ITEM_HELP` in the dialog(1) manual page.

Note

- `DIALOG_HELP` and `DIALOG_ITEM_HELP` both map to `Dialog.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 a `Dialog` attribute, because it is automatically translated into a `DialogError` 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.

## Adding an Extra button

With most widgets, it is possible to add a supplementary button called Extra button. To do that, you simply have to use `extra_button=True` (keyword argument) in the widget call. By default, the button text is “Extra”, but you can specify another string with the extra_label keyword argument.

When the widget exits, you know if the Extra button was pressed if the Dialog exit code is `Dialog.EXTRA` (`"extra"`). Normally, the rest of the return value is the same as if the widget had been closed with OK. Therefore, if the widget normally returns a list of three integers, for instance, you can expect to get the same information if Extra is pressed instead of OK.

Note

This feature can be particularly useful in combination with the yes_label, no_label, help_button and help_label common options to provide a completely different set of buttons than the default for a given widget.

## 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.

### Adding a Help button

In order to provide a Help button in addition to the normal buttons of a widget, you can pass `help_button=True` (keyword argument) to the corresponding `Dialog` method. For instance, if d is a `Dialog` instance, you can write:

    code = d.yesno("<text>", height=10, width=40, help_button=True)

or:

    code, answer = d.inputbox("<text>", init="<init>",
                              help_button=True)

When the method returns, the Dialog exit code is `Dialog.HELP` (i.e., the string `"help"`) if the user pressed the Help button. Apart from that, it works exactly as if `help_button=True` had not been used. In the last example, if the user presses the Help button, answer will contain the user input, just as if OK had been pressed. Similarly, if you write:

    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)

and find that `code == Dialog.HELP`, then t contains the tag string for the highlighted item when the Help button was pressed.

Finally, note that it is possible to choose the text written on the Help button by supplying a string as the help_label keyword argument.

### 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).

### Getting the widget status before the Help button was pressed

Typically, when the user chooses Help in a widget, the application will display a dialog box such as `textbox()`, `msgbox()` or `scrollbox()` and redisplay the original widget afterwards. For simple widgets such as `inputbox()`, when the Dialog exit code is equal to `Dialog.HELP`, the return value contains enough information to redisplay the widget in the same state it had when Help was chosen. However, for more complex widgets such as `radiolist()` (resp. `checklist()`, or `form()` and its derivatives), knowing the highlighted item is not enough to restore the widget state after processing the help request: one needs to know the checked item (resp. list of checked items, or form contents).

This is where the help_status keyword argument becomes useful. Example:

    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, help_status=True)

When Help is chosen, `code == Dialog.HELP` and t is a tuple of the form `(tag, selected_tags, choices)` where:

> - tag gives the tag string of the highlighted item (which would be the value of t if help_status were set to `False`);
> - selected_tags is the... list of selected tags (note that highlighting and selecting an item are different things!);
> - choices is a list built from the original choices argument of the `checklist()` call and from the list of selected tags, that can be used as is to create a widget with the same items and selection state as the original widget had when Help was chosen.

Normally, pythondialog should always provide something similar to the last item in the previous example in order to make it as easy as possible to redisplay the widget in the appropriate state. To know precisely what is returned with `help_status=True`, the best way is probably to experiment and/or read the code (by the way, there are many examples of widgets with various combinations of the help_button, item_help and help_status keyword arguments in the demo).

Note

The various options related to help support are not mutually exclusive; they may be used together to provide good help support.

It is also worth noting that the documentation of the various widget-producing methods is written, in most cases, under the assumption that the widget was closed “normally” (typically, with the OK or Extra button). For instance, a widget documentation may state that the method returns a tuple of the form `(code, tag)` where tag is ..., but actually, if using `item_help=True` with `help_tags=False`, the tag may very well be an item-help string, and if using `help_status=True`, it is likely to be a structured object such as a tuple or list. Of course, handling all these possible variations for all widgets would be a tedious task and would probably significantly degrade the readability of said documentation.

New in version 3.0: Proper support for the item_help and help_status common options.

## Screen-related methods

Getting the terminal size:

`Dialog.``maxsize`(**kwargs)

  Get the maximum size of dialog boxes.

  If the exit status from the backend corresponds to `Dialog.OK`, return a `(lines, cols)` tuple of integers; otherwise, return `None`.

  If you want to obtain the number of lines and columns of the terminal, you should call this method with `use_persistent_args=False`, because dialog options such as `--backtitle` modify the returned values.

  Notable exceptions:

  > - `PythonDialogReModuleError`
  > - any exception raised by `Dialog._perform()`

  New in version 2.12.

`Dialog.``set_background_title`(text)

  Set the background title for dialog.

  Parameters: | text (str) – string to use as background title

  New in version 2.13.

### Obsolete methods

`Dialog.``setBackgroundTitle`(text)

  Set the background title for dialog.

  Parameters: | text (str) – background title to use behind widgets

  Deprecated since version 2.03: Use `set_background_title()` instead.

`Dialog.``clear`()

  Clear the screen.

  Equivalent to the `--clear` option of dialog.

  Deprecated since version 2.03: You may use the clear(1) program instead. cf. `clear_screen()` in `examples/demo.py` for an example.

## Checking the versions of pythondialog and its backend

### Version of pythondialog

class `dialog.``VersionInfo`

  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.

  `__str__`()

    Return a string representation of the version.

`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 the `Dialog` constructor and used to store the backend version, avoiding the need to repeatedly call `dialog --print-version` or a similar command, depending on the backend.

  When using the dialog backend, `Dialog.cached_backend_version` is a `DialogBackendVersion` instance.

`Dialog.``backend_version`()

  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 of `Dialog` 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 with `str()`.

  Notable exceptions:

  > - `UnableToRetrieveBackendVersion`
  > - `PythonDialogReModuleError`
  > - any exception raised by `Dialog._perform()`

  New in version 2.12.

  Changed in version 2.14: Raise `UnableToRetrieveBackendVersion` instead of returning `None` 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)

  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 written
  - expand_file_opt (bool) – when `Dialog.__init__()` has been called with `pass_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 with `pass_args_via_file=False` (but contrary to `pass_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 or `pass_args_via_file=False` in `Dialog.__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)

  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()` and `dash_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)

  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 as `add_persistent_args()`.

  New in version 2.12.

classmethod `Dialog.``dash_escape_nf`(args)

  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 as `add_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"]))