[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Button Widgets


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 Normal Buttons

We have almost seen all there is to see of the button widget, which is represented by the gtk-button class. The button widget is pretty simple. There is however more than one way to create a button. You can use the the function gtk-button-new-with-label or the function gtk-button-new-with-mnemonic to create a button with a label, use gtk-button-new-from-stock to create a button containing the image and text from a stock item or use gtk-button-new to create a blank button. It is then up to you to pack a label or pixmap into this new button. To do this, create a new box, and then pack your objects into this box using the function gtk-box-pack-start, and then use the function gtk-container-add to pack the box into the button.

figures/button158x90

Figure 4.1: Button with an image from a file

figure-button is an example of using gtk-button-new to create a button with an image and a label in it. The image is loaded from a file with the function gtk-image-new-from-file. The code to create a box is shown in example-image-label-box and breaken up from the rest so you can use it in your programs. The main program which uses this subroutine is shown in example-button.

The image-label-box function could be used to pack images and labels into any widget that can be a container.

figure-buttons shows more buttons, which are created with standard functions and with the function make-instance. To get buttons which show both a label and an image the global setting of the property gtk-button-images has to be set to the value T. The code of figure-buttons is shown in example-buttons.

Example 4.1: A button with an image and a label

(defun example-button ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Cool Button"
                                 :type :toplevel
                                 :border-width 12))
          (button (make-instance 'gtk-button))
          (box (image-label-box "save.png" "Save to File")))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (gtk-container-add button box)
      (gtk-container-add window button)
      (gtk-widget-show-all window))))

Example 4.2: Code to create a button with an image and a label

(defun image-label-box (filename text)
  (let ((box (make-instance 'gtk-box
                            :orientation :horizontal
                            :border-width 3))
        (label (make-instance 'gtk-label
                              :label text))
        (image (gtk-image-new-from-file filename)))
    (gtk-box-pack-start box image :expand nil :fill nil :padding 3)
    (gtk-box-pack-start box label :expand nil :fill nil :padding 3)
    box))

figures/buttons256x185

Figure 4.2: More Examples to create buttons

Example 4.3: More buttons

(defun example-buttons ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Buttons"
                                 :type :toplevel
                                 :default-width 250
                                 :border-width 12))
          (vbox1 (make-instance 'gtk-box
                                :orientation :vertical
                                :spacing 6))
          (vbox2 (make-instance 'gtk-box
                                :orientation :vertical
                                :spacing 6))
          (hbox  (make-instance 'gtk-box
                                :orientation :horizontal
                                :spacing 6)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      ;; Set gtk-button-images to T. This allows buttons with text and image.
      (setf (gtk-settings-gtk-button-images (gtk-settings-get-default)) t)
      ;; These are the standard functions to create a button.
      (gtk-box-pack-start vbox1
                          (gtk-button-new-with-label "Label"))
      (gtk-box-pack-start vbox1
                          (gtk-button-new-with-mnemonic "_Mnemonic"))
      (gtk-box-pack-start vbox1
                          (gtk-button-new-from-stock "gtk-apply"))
      ;; Create some buttons with make-instance.
      (gtk-box-pack-start vbox2
                          (make-instance 'gtk-button
                                         :image-position :right
                                         :image
                                         (gtk-image-new-from-stock "gtk-edit"
                                                                   :button)
                                         :label "gtk-edit"
                                         :use-stock t))
      (gtk-box-pack-start vbox2
                          (make-instance 'gtk-button
                                         :image-position :top
                                         :image
                                         (gtk-image-new-from-stock "gtk-cut"
                                                                   :button)
                                         :label "gtk-cut"
                                         :use-stock t))
      (gtk-box-pack-start vbox2
                          (make-instance 'gtk-button
                                         :image-position :bottom
                                         :image
                                         (gtk-image-new-from-stock
                                                                 "gtk-cancel"
                                                                 :button)
                                         :label "gtk-cancel"
                                         :use-stock t))
      (gtk-box-pack-start hbox vbox1)
      (gtk-box-pack-start hbox vbox2)
      (gtk-container-add window hbox)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 Toggle Buttons

Toggle buttons are derived from normal buttons and are very similar, except toggle buttons always are in one of two states, alternated by a click. Toggle buttons can be depressed, and when clicked again, the toggle button will pop back up. Toggle buttons are the basis for check buttons and radio buttons, as such, many of the calls used for toggle buttons are inherited by radio and check buttons.

Beside make-instance, toggle buttons can be created with the functions gtk-toggle-button-new, gtk-toggle-button-new-with-label, and gtk-toggle-button-new-with-mnemonic. The first function creates a blank toggle button, and the last two functions, a toggle button with a label widget already packed into it. The gtk-toggle-button-new-with-mnemonic variant additionally parses the label for '_'-prefixed mnemonic characters.

To retrieve the state of the toggle widget, including radio and check buttons, a construct as shown in the example below is used. This tests the state of the toggle button, by accessing the active field of the toggle widget's structure with the function gtk-toggle-button-active. The signal of interest to us emitted by toggle buttons (the toggle button check button, and radio button widgets) is the "toggled" signal. To check the state of these buttons, set up a signal handler to catch the toggled signal, and access the property active to determine the state of the button. A signal handler will look something like:

(g-signal-connect button "toggled"
   (lambda (widget)
     (if (gtk-toggle-button-active widget)
         (progn
           ;; If control reaches here, the toggle button is down
         )
        (progn
           ;; If control reaches here, the toggle button is up
         ))))

To force the state of a toggle button, and its children, the radio and check buttons, use this function gtk-toggle-button-active. This function can be used to set the state of the toggle button, and its children the radio and check buttons. Passing in your created button as the first argument, and a T or NIL for the second state argument to specify whether it should be down (depressed) or up (released). Default is up, or NIL.

Note that when you use the gtk-toggle-button-active function, and the state is actually changed, it causes the "clicked" and "toggled" signals to be emitted from the button. The current state of the toggle button as a boolean T or NIL value is returned from the generic function gtk-toggle-button-active.

In example-table-packing-2 the usage of toggle buttons is shown.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.3 Check Buttons

Check buttons are implemented as the class gtk-check-button and inherit many properties and functions from the toggle buttons above, but look a little different. Rather than being buttons with text inside them, they are small squares with the text to the right of them. These are often used for toggling options on and off in applications.

The creation functions are similar to those of the normal button: gtk-check-button-new, gtk-check-button-new-with-label, and gtk-check-button-new-with-mnemonic. The gtk-check-button-new-with-label function creates a check button with a label beside it.

Checking the state of the check button is identical to that of the toggle button. figure-toggle-buttons shows toggle buttons and example-toggle-buttons the code to create toggle buttons.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.4 Radio Buttons

Radio buttons are similar to check buttons except they are grouped so that only one may be selected or depressed at a time. This is good for places in your application where you need to select from a short list of options.

Creating a new radio button is done with one of these calls: gtk-radio-button-new, gtk-radio-button-new-with-label, and gtk-radio-button-new-with-mnemonic. These functions take a list of radio buttons as the first argument or NIL. When NIL a new list of radio buttons is created. The newly created list for the radio buttons can be get with the function gtk-radio-button-get-group. More radio buttons can then be added to this list. The important thing to remember is that gtk-radio-button-get-group must be called for each new button added to the group, with the previous button passed in as an argument. The result is then passed into the next call to gtk-radio-button-new or the other two functions for creating a radio button. This allows a chain of buttons to be established. example-toggle-buttons creates a radio button group with three buttons.

You can shorten this slightly by using the following syntax, which removes the need for a variable to hold the list of buttons:

(setq button
      (gtk-radio-button-new-with-label (gtk-radio-button-get-group button)
                                       "Button"))

Each of these functions has a variant, which take a radio button as the first argument and allows to omit the gtk-radio-button-get-group call. In this case the new radio button is added to the list of radio buttons the argument is already a part of. These functions are: gtk-radio-button-new-from-widget, gtk-radio-button-new-with-label-from-widget, and gtk-radio-button-new-with-mnemonic-from-widget.

figures/toggle-buttons305x201

Figure 4.3: Toggle Buttons

It is also a good idea to explicitly set which button should be the default depressed button with the function gtk-toggle-button-active. This is described in the section on toggle buttons, and works in exactly the same way. Once the radio buttons are grouped together, only one of the group may be active at a time. If the user clicks on one radio button, and then on another, the first radio button will first emit a "toggled" signal (to report becoming inactive), and then the second will emit its "toggled" signal (to report becoming active).

Example 4.4: Radio and Toggle Buttons

(defun example-toggle-buttons ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Toggle Buttons"
                                 :type :toplevel))
          (vbox (make-instance 'gtk-box
                               :orientation :vertical))
          (hbox (make-instance 'gtk-box
                               :orientation :horizontal)))
      ;; Handler for the signal "destroy"
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      ;; Create three radio buttons and put the buttons in a vbox
      (let ((vbox (make-instance 'gtk-box
                                 :orientation :vertical
                                 :spacing 12
                                 :border-width 12))
            (button (gtk-radio-button-new-with-label nil "Radio Button 1")))
        (gtk-box-pack-start vbox button)
        (setq button
              (gtk-radio-button-new-with-label
                                          (gtk-radio-button-get-group button)
                                          "Radio Button 2"))
        (setf (gtk-toggle-button-active button) t)
        (gtk-box-pack-start vbox button)
        (setq button
              (gtk-radio-button-new-with-mnemonic
                                          (gtk-radio-button-get-group button)
                                          "_Radio Button 3"))
        (gtk-box-pack-start vbox button)
        ;; Put the vbox with the radio buttons in a hbox
        (gtk-box-pack-start hbox vbox :expand nil :fill nil))
      ;; Create three check buttons and put the buttons in a vbox
      (let ((vbox (make-instance 'gtk-box
                                 :orientation :vertical
                                 :homogeneous nil
                                 :spacing 12
                                 :border-width 12)))
        (gtk-box-pack-start
                          vbox
                          (gtk-check-button-new-with-label "Check Button 1"))
        (gtk-box-pack-start
                          vbox
                          (gtk-check-button-new-with-label "Check Button 2"))
        (gtk-box-pack-start
                          vbox
                          (gtk-check-button-new-with-label "Check Button 3"))
        ;; Put the vbox with the buttons in a hbox
        (gtk-box-pack-start hbox vbox :expand nil :fill nil))
      ;; Put the hbox in a vbox
      (gtk-box-pack-start vbox hbox :expand nil :fill nil)
      ;; Add a separator to the vbox
      (gtk-box-pack-start vbox
                          (make-instance 'gtk-separator
                                         :orientation :horizontal)
                          :expand nil :fill nil)
      ;; Add a quit button to the vbox
      (let ((vbox-quit (make-instance 'gtk-box
                                      :orientation :vertical
                                      :spacing 12
                                      :border-width 12))
            (button (make-instance 'gtk-button :label "Close")))
        (gtk-box-pack-start vbox-quit button :expand nil :fill nil)
        (gtk-box-pack-start vbox vbox-quit :expand nil)
        (g-signal-connect button "clicked"
                          (lambda (button)
                            (declare (ignore button))
                            (gtk-widget-destroy window))))
      ;; Put the vbox in the window widget
      (gtk-container-add window vbox)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 Link Buttons

figures/link-button272x159

Figure 4.4: Link Buttons

A gtk-link-button is a gtk-button with a hyperlink, similar to the one used by web browsers, which triggers an action when clicked. It is useful to show quick links to resources.

A link button is created by calling either the functions gtk-link-button-new or gtk-link-button-new-with-label. If using the former, the URI you pass to the constructor is used as a label for the widget.

The URI bound to a gtk-link-button can be set specifically or retrieved using the generic function gtk-link-button-uri.

By default, gtk-link-button calls gtk-show-uri when the button is clicked. This behaviour can be overridden by connecting to the "activate-link" signal and returning T from the signal handler.

figure-link-button shows two different styles of link buttons. The code is shown in example-link-button.

Example 4.5: Link Buttons

(defun example-link-button ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Link Button"
                                 :default-width 270
                                 :border-width 12))
          (grid (make-instance 'gtk-grid
                               :orientation :vertical
                               :row-spacing 6
                               :column-homogeneous t)))
      (g-signal-connect window "destroy"
                               (lambda (widget)
                                 (declare (ignore widget))
                                 (leave-gtk-main)))
      (gtk-container-add grid
                         (make-instance 'gtk-label
                                        :use-markup t
                                        :label
                                        "<b>Link Button with url</b>"))
      (gtk-container-add grid
                         (gtk-link-button-new "http://www.gtk.org/"))
      (gtk-container-add grid
                         (make-instance 'gtk-label
                                        :use-markup t
                                        :label
                                        "<b>Link Button with Label</b>"))
      (gtk-container-add grid
                         (gtk-link-button-new-with-label
                                                        "http://www.gtk.org/"
                                                        "Project WebSite"))
      (gtk-container-add window grid)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.6 Switches

figures/switch232x100

Figure 4.5: Switch

gtk-switch is a widget that has two states: on or off. The user can control which state should be active by clicking the empty area, or by dragging the handle. The switch is created with the function gtk-switch-new or the call (make-instance 'gtk-switch).

gtk-switch has the property active, which can be set or retrieved with the generic function gtk-switch-set-active.

An example of a switch is shown in figure-switch. The code is shown in example-switch. Note that in the example the signal "notify::active" is connected to the switch to display a label with the state of the switch.

Example 4.6: Switches

(defun example-switch ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Switch"
                                 :default-width 230
                                 :border-width 12))
          (switch (make-instance 'gtk-switch
                                 :active t))
          (label (make-instance 'gtk-label
                                :label "The Switch is ON"))
          (grid (make-instance 'gtk-grid
                               :orientation :vertical
                               :row-spacing 6
                               :column-homogeneous t)))
      (g-signal-connect window "destroy"
                               (lambda (widget)
                                 (declare (ignore widget))
                                 (leave-gtk-main)))
      (g-signal-connect switch "notify::active"
         (lambda (widget param)
           (declare (ignore param))
           (if (gtk-switch-active widget)
               (setf (gtk-label-label label) "The Switch is ON")
               (setf (gtk-label-label label) "The Switch is OFF"))))
      (gtk-container-add grid switch)
      (gtk-container-add grid label)
      (gtk-container-add window grid)
      (gtk-widget-show-all window))))

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Crategus on January, 10 2016 using texi2html 1.76.