1.. currentmodule:: dialog 2 3A gentle introduction 4===================== 5 6A minimal program using pythondialog starts with the creation of a 7:class:`Dialog` instance:: 8 9 from dialog import Dialog 10 11 d = Dialog(dialog="cdialog") 12 13The *dialog* parameter indicates the executable to use to invoke the backend 14(which must be compatible with dialog_). For instance, one might use something 15like ``dialog="/home/dave/src/dialog-1.2-20140219/dialog"``. The default value 16is ``"dialog"``, and since it does not contain any slash (``/``), it is looked 17up according to the :envvar:`PATH` environment variable. See 18:meth:`Dialog.__init__` for a description of all parameters that can be passed 19to the :class:`Dialog` constructor. 20 21.. _dialog: https://invisible-island.net/dialog/dialog.html 22 23 24Offering a choice between several options using :meth:`!menu` 25------------------------------------------------------------- 26 27Once you have a :class:`Dialog` instance, you can call any widget-producing 28method, as documented in :ref:`widgets`. For instance, if you want to display 29a menu offering three choices:: 30 31 code, tag = d.menu("Some text that will be displayed above the menu entries", 32 choices=[("Tag 1", "Item text 1"), 33 ("Tag 2", "Item text 2"), 34 ("Tag 3", "Item text 3")]) 35 36When the method returns: 37 38 - *code* will be equal to ``d.OK`` if there was no error and the user chose 39 an entry (instead of pressing :kbd:`Esc`). See :ref:`Dialog-exit-code` for 40 more details on how to interpret the value of *code*. 41 - *tag* will contain the name of the tag corresponding to the selected 42 entry: ``"Tag 1"``, ``"Tag 2"`` or ``"Tag 3"`` (assuming that ``code == 43 d.OK``). 44 45While we kept this :meth:`~Dialog.menu` example as simple as possible, it 46would be very easy to add a title line at the top of the widget window. For 47this, all you need to do is to add a :samp:`title={...}` keyword argument to 48the :meth:`~!Dialog.menu` method call. It is also possible to display a 49background title using :samp:`backtitle={...}`, and in case you want the same 50background title for all widgets, :meth:`Dialog.set_background_title` is your 51friend. 52 53.. figure:: ../screenshots/intro/example-menu.png 54 :align: center 55 56 A simple example using :meth:`Dialog.menu` 57 58 59Displaying a message with :meth:`~!Dialog.msgbox` 60------------------------------------------------- 61 62We can expand on the previous example by displaying an :meth:`~Dialog.msgbox` 63indicating what the user has done to exit from the :meth:`~Dialog.menu`. 64First, we can define a mapping from the :term:`Dialog exit codes <Dialog exit 65code>` for the standard buttons to the corresponding button labels:: 66 67 button_names = {d.OK: "OK", 68 d.CANCEL: "Cancel", 69 d.HELP: "Help", 70 d.EXTRA: "Extra"} 71 72Of course, in the previous :meth:`~Dialog.menu` widget call, the only codes 73that can be returned are ``d.OK`` and ``d.CANCEL``, respectively corresponding 74to the :guilabel:`OK` and :guilabel:`Cancel` buttons. Thus, we could do with 75only two key-value pairs in ``button_names`` for this particular example, 76however it seems cleaner and not outrageously expensive to declare the codes 77for the four standard buttons like this. 78 79In addition to these :term:`Dialog exit codes <Dialog exit code>`, the 80:meth:`~Dialog.menu` widget call can return ``d.ESC``, indicating that the 81user pressed the :kbd:`Esc` key. Therefore, we are going to check for this one 82too. Here it goes:: 83 84 if code == d.ESC: 85 d.msgbox("You got out of the menu by pressing the Escape key.") 86 else: 87 text = "You got out of the menu by choosing the {} button".format( 88 button_names[code]) 89 90 if code != d.CANCEL: 91 text += ", and the highlighted entry at that time had tag {!r}".format( 92 tag) 93 94 d.msgbox(text + ".", width=40, height=10) 95 96(users of Python < 3.1 should replace ``{}`` with ``{0}`` and ``{!r}`` with 97``{0!r}``) 98 99The above code for dealing with the :kbd:`Esc` key is pretty straightforward. 100It relies on the default values to determine the width and height of the 101:meth:`~Dialog.msgbox`, which are acceptable in this case. On the other hand, 102the default width for :meth:`~!Dialog.msgbox` seemed too small for the message 103displayed in the *else* clause, causing very irregular line lengths. In order 104to compensate for this problem, we have explicitely specified the width and 105height of the :meth:`~!Dialog.msgbox` using keyword arguments 106(``width=40, height=10``). 107 108.. figure:: ../screenshots/intro/example-msgbox.png 109 :align: center 110 111 A message displayed with :meth:`Dialog.msgbox` 112 113 114Displaying a transient message with :meth:`~!Dialog.infobox` 115------------------------------------------------------------ 116 117We can finish this little example with a widget call that displays a message 118and immediately returns to the caller without waiting for the user to react. 119Typically, the :meth:`~Dialog.infobox` is used to display some information 120while a time-consuming operation is being performed. In this case, since we 121don't have anything particularly useful to do but still want the user to be 122able to read the message, we are going to wait using :func:`time.sleep`:: 123 124 d.infobox("Bye bye...", width=0, height=0, title="This is the end") 125 time.sleep(2) 126 127We also addressed the problem of determining the widget size in a different 128way as exposed earlier. By using ``width=0, height=0``, we ask 129:program:`dialog` to automatically determine suitable width and height 130parameters for the dialog box. If you like this method and would like to have 131it used by default for all widgets without having to specify ``width=0, 132height=0`` every time, you can enable the :ref:`autowidgetsize feature 133<autowidgetsize>`. 134 135For the sake of the example, we've also specified a window title for the 136:meth:`~Dialog.infobox` using a :samp:`title={...}` keyword argument. This can 137be done with most widgets, and is entirely optional. 138 139.. figure:: ../screenshots/intro/example-infobox.png 140 :align: center 141 142 A transient message displayed with :meth:`Dialog.infobox` 143 144Of course, the :func:`time.sleep` call requires an:: 145 146 import time 147 148statement that you, careful reader, had already added. In order to exit 149cleanly from our program, I also suggest to end with:: 150 151 sys.exit(0) 152 153which requires an:: 154 155 import sys 156 157at the top of your script. And finally, since you don't want to take bad 158habits, I would also suggest starting your program with:: 159 160 locale.setlocale(locale.LC_ALL, '') 161 162which in turn requires an:: 163 164 import locale 165 166at the top. 167 168 169Putting it all together 170----------------------- 171 172If we put all the pieces from this chapter together and reorder a tiny bit to 173improve readability, we obtain the code for our example program:: 174 175 import sys 176 import locale 177 import time 178 179 from dialog import Dialog 180 181 # This is almost always a good thing to do at the beginning of your programs. 182 locale.setlocale(locale.LC_ALL, '') 183 184 d = Dialog(dialog="cdialog") 185 186 button_names = {d.OK: "OK", 187 d.CANCEL: "Cancel", 188 d.HELP: "Help", 189 d.EXTRA: "Extra"} 190 191 code, tag = d.menu("Some text that will be displayed above the menu entries", 192 choices=[("Tag 1", "Item text 1"), 193 ("Tag 2", "Item text 2"), 194 ("Tag 3", "Item text 3")]) 195 196 if code == d.ESC: 197 d.msgbox("You got out of the menu by pressing the Escape key.") 198 else: 199 text = "You got out of the menu by choosing the {} button".format( 200 button_names[code]) 201 202 if code != d.CANCEL: 203 text += ", and the highlighted entry at that time had tag {!r}".format( 204 tag) 205 206 d.msgbox(text + ".", width=40, height=10) 207 208 d.infobox("Bye bye...", width=0, height=0, title="This is the end") 209 time.sleep(2) 210 211 sys.exit(0) 212 213 214Other examples 215-------------- 216 217For an example that is slightly different from the one exposed in this 218chapter, you can look at the :file:`simple_example.py` file that comes with 219pythondialog, in the :file:`examples` directory. It is a very simple and 220straightforward example using a few basic widgets. The `pythondialog website 221<http://pythondialog.sourceforge.net/>`_ also has a very simple example that 222can be used to get started. 223 224Once you are comfortable with the basics, you can study the :file:`demo.py` 225file that illustrates most features of pythondialog (also from the 226:file:`examples` directory), or more directly :file:`dialog.py`. 227