261. How to use GtkSheet - Part 14 - setup radio buttons in cell?

Problem

You would like to display radio buttons in a GtkSheet for user selection as shown below:

How to use GtkSheet - Part 14 - setup radio buttons in cell?


Solution

  • Make sure your version of PHP-GTK2 has the GtkExtra library, and the feature turned on in php.ini. (See notes below.)
  • Everything is the same as outlined in How to use GtkSheet - Part 9 - using attach with justification?
  • The only difference is that instead of attaching a GtkLabel, we just attach a GtkRadioButton!

Important Note: This only works for PHP-GTK2 compliled with the additional library GtkExtra. For linux, you can download the files from http://gtkextra.sourceforge.net/ and do a recompile. For windows, you may use the builds by Elizabeth Smith or the official php-gtk2 beta release available at http://gtk.php.net/download.php. Both contain all the required gtkextra libraries and dll's. In the php.ini, don't forget to add php-gtk.extensions = php_gtk_extra2.dll to turn on GtkExtra.


Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
53   
54   
57   
58   
59   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
103   
104   
105   
106   
107   
108   
113   
114   
117   
118   
119   
120   
121   
122   
123   
124   
125   
126   
127   
128   
129   
131   
132   
136   
137   
138   
139   
140   
141   
142   
143   
144   
145   
146   
147   
148   
149   
150   
151   
152   
157   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(430, 250);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Using GtkSheet\n".
"Part 14 - setup radio buttons in cell");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$title->set_justify(Gtk::JUSTIFY_CENTER);
$alignment = new GtkAlignment(0.5, 0, 0, 0);
$alignment->add($title);
$vbox->pack_start($alignment, 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);
$vbox->pack_start($hbox = new GtkHBox(), 0);
$hbox->pack_start($button = new GtkButton('Get Selections'), 0);

// the 2D table
$data = array(
array('', 'row0', 'item 42', 2, 3.1),
array('', 'row1', 'item 36', 20, 6.21),
array('', 'row2', 'item 21', 8, 9.36),
array('', 'row3', 'item 10', 11, 12.4),
array('', 'row4', 'item 7', 5, 15.5),
array('', 'row5', 'item 4', 17, 18.6),
array('', 'row6', 'item 3', 20, 21.73));

$max_col = count($data[0])-1;
$max_row = count($data)-1;

$field_header = array('Select Type', 'Row #', 'Description', 'Qty', 'Price');
$justification = array('CENTER', 'LEFT', 'LEFT', 'CENTER', 'CENTER');

$sheet = display_table($vbox, $data, $field_header, $justification);

$button->connect('clicked', 'get_selection', $sheet);
$window->show_all();
Gtk::main();

function display_table($vbox, $data, $field_header, $justification) {

    $scrolled_win = new GtkScrolledWindow();
    $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC,
        Gtk::POLICY_AUTOMATIC);
    $vbox->pack_start($scrolled_win);

    $sheet = GtkSheet::new_browser(count($data), count($data[0]), 'Test 123');
    $sheet->set_autoresize(1);
    $scrolled_win->add($sheet);

    $sheet->connect('key-press-event', 'on_keypress');

    // set column header
    for ($col=0; $col<count($field_header); ++$col) {
        $sheet->column_button_add_label($col, $field_header[$col]);
        $justify = constant("Gtk::JUSTIFY_".$justification[$col]);
        $sheet->column_button_justify($col, $justify);
    }

    global $eventbox;
    global $radio_buttons;
    $alignment_val = array('LEFT'=>0.0, 'CENTER'=>0.5, 'RIGHT'=>1.0);
    for ($row=0; $row<count($data); ++$row) {
        $sheet->row_button_add_label($row, $row+1);
        for ($col=0; $col<count($data[$row]); ++$col) {
            $eventbox[$row][$col] = new GtkEventBox();
            $alignment = new GtkAlignment(
                $alignment_val[$justification[$col]], 0.5, 0, 0);
            $alignment->set_padding(0, 0, 2, 2);

            if ($col==0) {
                $hbox = new GtkHBox();
                $radio0 = new GtkRadioButton(null, 'type0'); // note 1
                $radio_buttons[$row][1] = new GtkRadioButton($radio0, 'A'); // note 2
                $radio_buttons[$row][2] = new GtkRadioButton($radio0, 'B'); // note 2
                $radio_buttons[$row][3] = new GtkRadioButton($radio0, 'C'); // note 2
                $hbox->pack_start($radio_buttons[$row][1] , 0);
                $hbox->pack_start($radio_buttons[$row][2] , 0);
                $hbox->pack_start($radio_buttons[$row][3] , 0);
                $alignment->add($hbox); // note 3
            } else {
                $alignment->add(new GtkLabel($data[$row][$col])); // note 4
            }
            $eventbox[$row][$col]->add($alignment);
            $row_color = ($row%2==1) ? '#dddddd' : '#ffffff';
            $eventbox[$row][$col]->modify_bg(Gtk::STATE_NORMAL,
                GdkColor::parse($row_color));
            $sheet->attach_default($eventbox[$row][$col], $row, $col);
        }
    }
    return $sheet;
}

function on_keypress($sheet, $event) {
    global $max_col, $max_row;
    list($row, $col) = $sheet->get_active_cell();
    if ($event->keyval == Gdk::KEY_Tab) {
        if ($col<$max_col || $row==$max_row) return false;
        $sheet->set_active_cell($row+1, 0);
        return true;
    } else {
        return false;
    }
}

function get_selection($button, $sheet) {
    global $eventbox, $radio_buttons;
    $num_rows = $sheet->get_rows_count();
    $num_cols = $sheet->get_columns_count();
    $selections = array();
    for ($row=0; $row<$num_rows; ++$row) {
        for ($i=1; $i<=3; ++$i) {
            if ($radio_buttons[$row][$i]->get_active()) { // note 5
                switch ($i) {
                    case 1: $type = 'A'; break;
                    case 2: $type = 'B'; break;
                    case 3: $type = 'C'; break;
                }
                $id = $eventbox[$row][1]->child->child->get_text();
                $desc = $eventbox[$row][2]->child->child->get_text();
                $selections[] = "$id ($desc): Type = $type"; // note 6
            }
        }
    }
    echo("Selections:");
    print_r($selections); // note 7
}

?>

Output

As shown above.
 

Explanation

The example above makes use of the code from How to use GtkSheet - Part 9 - using attach with justification?

What's new here:

  1. Set up the GtkRadioButtons. Note that I used the technique as described in How to set up radio buttons with default all unselected? so that no radio buttons are selected when the application is first started.
  2. Note that we store the pointer to each radio button in the array $radio_buttons[$row][$i] so that we have easy access to these buttons later to check which one is selected.
  3. Attach the radio butotns to the cell.
  4. For all other columns, we use GtkLabel for standard text.
  5. Check which of the radio button is selected.
  6. Add the selected radio button to the array $selections
  7. Here we simply output the selected rows to the command window. In your applications, you can perform any actions based on user's selections.

Note

Note that in this example, I set the spreadsheet in browser mode for browse and selection only. Only the radio buttons are selectable. If you wish to set the entire spreadsheet to be editable, you may refer to the example How to use GtkSheet - Part 11 - setup combobox in cell?

Also, as I've mentioned in the blog, there's some problem with this method.

Try pressing the Tab key. Did you see the underlying GtkItemEntry?

I'm not sure if this is a feature or a bug. Although I could find some ways to "gobble" up the Tab or arrow keys so that the GtkItemEntry doesn't appear, I know this should not be the right way of doing things.

Anybody knows how to "deactivate" the underlying GtkItemEntry?

Related Links

Add comment


Security code
Refresh