The askMulti Dialog — FontForge 20230101 documentation

# The askMulti Dialog

When called in a UI-enabled environment the Python `fontforge.askMulti()` method raises a modal dialog that prompts the user to answer one or more questions, potentially organized into “categories” displayed in separate tabs. It takes two parameters, `title` and `specification`.

The `title` parameter should be a string that will be displayed in the dialog window title bar.

The `specification` paramter is either a Python list or dictionary object specifying the questions. This is explained below.

## Questions

There are four question types, corresponding to the single-question `fontforge.askString()`, `fontforge.askChoices()`, `fontforge.openFilename()`, and `fontforge.saveFilename()` dialog methods. Each individual question is specified as a dictionary.

All question types use the keys `type`, `question```, `tag` and `align`. The `type` value specifies the type of question as outlined below.

The value corresponding to `question` is the label string, which is displayed before the answer field. This key must be present but the value can be `None` if no label is needed.

The `tag` is optional but either it or `question` must have a value. When present its value will be used as the key corresponding to this question in the result dictionary returned by the method. Otherwise the `question` value will be used. The `tag` value can be any “hashable” type—that is, any type that can serve as a key in a Python dictionary.

The `align` value must be boolean-evaluable (ideally `True` or `False`). It indicates whether, when the dialog is being laid out, the label for this question should be aligned with the other labels of the same category. When absent the default is `True`. (This has no effect when the `question` value is `None`, so if you want an aligned, empty label use a space as the `question` value.)

### String Questions

A string question displays the label followed by a text entry field. Its `type` value must be “string”.

The only additional key for a string question is `default`, which is optional. When the key present its value, which must be a string, will be the initial value of the answer entry field. An example dictionary is:

    { 'type': 'string', 'question': 'Number of contours:',
       'tag': 3, 'default': '4' }

### Choice Questions

Choice questions ask the user to pick a subset of given answers. Its `type` value must be “choice”. This question type has three additional dictionary keys: `answers`, `multiple`, and `checks`.

The `answers` value must be a Python list of potential answers, each of which is its own small dictionary. The keys to an answer dictionary are `name`, `tag`, and `default`. The value of `name` must be the string the user will choose among. The value of `tag`, when present, will be used to report the answer in the result dictionary—when not present the `name` string will be used. Unlike the question `tag` an answer `tag` value can be of any type whatsoever. The `default` key is an optional key that must have a boolean-evaluable value. When `True` the answer is selected when the dialog is presented.

The `multiple` value must be boolean-evaluable; when the key is absent the default is `False`. It indicates whether the user must choose exactly one answer or can choose multiple or, potentially, no answers. When `multiple` is false there must be at most one answer for which `default` is `True`.

The `checks` value must also be boolean-evaluable and its default is also `False`. By default a choice question is presented as in the `fontforge.askChoices()` dialog, with a (potentially) scrolling vertical list similar to pop-up menu. When `checks` is `True` and `multiple` is `False` the answers are presented as radio buttons. When `checks` is `True` and `multiple` is `True` the answers are presented as checkboxes. Radio buttons and checkboxes allow better keyboard-based selection (see the mnemonics section) and may have other advantages.

An example choice question dictionary is:

    { 'type': 'choice', 'question': 'What direction:',
      'tag': 'direction', 'checks': True,
      'answers': [ { 'name': 'Clockwise', 'tag': 'cw', 'default': True },
                   { 'name': 'Counter-Clockwise', 'tag': 'ccw' } ]
    }

### Pathname Questions

The open pathname and save pathname questions have the respective type values “openpath” and “savepath”. These differ from the `fontforge.openFilename()` and `fontforge.saveFilename()` methods in that they do not raise a file browser directly. Instead they display an entry field, similar to a string question, followed by a button to raise a browser, similar to the path-specifying entries in :doc:`the preferences dialog </ui/dialogs/prefs>`. Each also has an optional `default` key for an initial pathname value, and an optional `filter` key to specify a file filter. Both must be strings. An example dictionary is:

    { 'type': 'openpath', 'question': 'Glif file:', 'tag': 'file',
      'default': 'input.glif', 'filter': '*.glif' }

## Categories

Questions are organized into categories. A category is a dictionary with two keys: `category` and `questions`. The value of `category` should be a either string to display to the user or `None` if no label is needed. The value of `questions` must be a list of question dictionaries, as described above. A category containing the dictionaries above looks like:

## The Specification

The specification passed as the `spec` parameter can be any of:

- A question dictionary

- A list of question dictionaries

- A category dictionary

- A list of category dictionaries

In the last case each category will be given its own tab, with the category names selectable on the left side of the dialog. (Whenever there is only one category there is no list, even when the category has a name.)

## The Return Value

When the user cancels the dialog, either with the “Cancel” button or by closing the window, the `askMulti` method returns None. Otherwise it returns a Python dictionary of results, one for each question. The key will be the `tag` value or, if none was present, the `question` string. For all question types other than “choice” the value is a string. For a choice question where `multiple` is `False` the value is the `tag` or `name` of the answer. For a `multiple` choice question the value is a tuple of `tag` or `name` values. The tuple may be empty.

A result dictionary for the collection above could be:

    {3: '20', 'direction': 'ccw', 'file': '/tmp/in.glif'}

When the specification is invalid the method will throw a `TypeError` or `ValueError` exception with information about the problem.