|
Problem You would like to capture key press, say left and right arrow, only when the treeview is in focus, i.e. when the user's mouse is somewhere inside the treeview as shown below:

Solution This might look simple. But when you tried it out, it's not that striaghtforward.
- If you set up
$treeview->connect('key-press-event', 'on_keypress'), you will find that you still receive key-press-events even when your cursor is outside treeview.
- $treeview->is_focus() only works when the user clicks somewhere inside the treeview. If user clicks somewhere outside the treeview, and then move the mouse inside the treeview,
$treeview->in_focus() will return a false.
The solution is to make use of the technique as explained in the article How to display tooltips in GtkTreeView - Part 2?
Sample Code Note: If you have installed php-gtk2 using Gnope Installer on Windows, and if running the sample code below gives you warning that the Symbolic names for keys (e.g. Gdk::KEY_Return) is not defined, you might want to update your php-gtk2 with the latest php-gtk2.dll available here. Simply download the php-gtk2.dll and replace the copy in the folder php-gtk2\ext. The latest compilation has put in the Symbolic names for keys listed here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| <?php $window = new GtkWindow(); $window->set_size_request(400, 300); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox());
// display title
$title = new GtkLabel("Capturing key-press-event in GtkTreeView\n"); $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); $vbox->pack_start($title, 0, 0); $vbox->pack_start(new GtkLabel( 'The following is active only when cursor is inside treeview'), 0, 0); $vbox->pack_start(new GtkLabel('Return - display detail'), 0, 0); $vbox->pack_start(new GtkLabel('Left Arrow - prev page'), 0, 0); $vbox->pack_start(new GtkLabel('Right Arrow - next page'), 0, 0); $vbox->pack_start(new GtkLabel('Alt Left Arrow - first page'), 0, 0); $vbox->pack_start(new GtkLabel('Alt Right Arrow - last page'), 0, 0); $vbox->pack_start(new GtkLabel(), 0, 0);
// the 2D table
$data = array( array('row0', 'item 19', 2, 3.1), array('row1', 'item 16', 20, 6.21), array('row2', 'item 13', 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));
$view_in_focus = 0; // note 1
display_table ($vbox, $data);
$window->show_all(); Gtk::main();
function display_table($vbox, $data) {
// Set up a scroll window
$scrolled_win = new GtkScrolledWindow(); $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $vbox->pack_start($scrolled_win);
// Creates the list store
if (defined("GObject::TYPE_STRING")) { $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING, GObject::TYPE_LONG, GObject::TYPE_DOUBLE); } else { $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING, Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE); } $field_header = array('Row #', 'Description', 'Qty', 'Price'); $field_justification = array(0.0, 0.0, 0.5, 1.0);
// Creates the view to display the list store
$view = new GtkTreeView($model); $scrolled_win->add($view);
// Creates the columns
for ($col=0; $col<count($field_header); ++$col) { $cell_renderer = new GtkCellRendererText(); $cell_renderer->set_property("xalign", $field_justification[$col]); $column = new GtkTreeViewColumn($field_header[$col], $cell_renderer, 'text', $col); $column->set_alignment($field_justification[$col]); $column->set_sort_column_id($col);
// set the header font and color
$label = new GtkLabel($field_header[$col]); $label->modify_font(new PangoFontDescription("Arial Bold")); $label->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000FF")); $column->set_widget($label); $label->show();
// setup self-defined function to display alternate row color
$column->set_cell_data_func($cell_renderer, "format_col", $col); $view->append_column($column); }
// pupulates the data
for ($row=0; $row<count($data); ++$row) { $values = array(); for ($col=0; $col<count($data[$row]); ++$col) { $values[] = $data[$row][$col]; } $model->append($values); }
// setup event handlers to let us know if mouse is in treeview
$view->connect('motion-notify-event', 'on_motion'); // note 2
$view->connect('leave-notify-event', 'on_leave'); // note 2
// setup selection
$selection = $view->get_selection(); $selection->connect('changed', 'on_selection');
$view->connect('key-press-event', 'on_key_press', $selection); // note 3
}
// set alternate row color
function format_col($column, $cell, $model, $iter, $col_num) { $path = $model->get_path($iter); // get the current path
$row_num = $path[0]; // get the row number
if ($col_num==3) { $amt = $model->get_value($iter, 3); $cell->set_property('text', '$'.number_format($amt,2)); } $row_color = ($row_num%2==1) ? '#dddddd' : '#ffffff'; $cell->set_property('cell-background', $row_color); }
// process user selection
function on_selection($selection) { list($model, $iter) = $selection->get_selected(); if ($iter==NULL) return; $desc = $model->get_value($iter, 1); $qty = $model->get_value($iter, 2); $price = $model->get_value($iter, 3); print "You have selected $desc: $qty ($price)\n"; }
function on_motion($view, $event) { // note 4
global $view_in_focus; // check if mouse is in column headers
|
- Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
- Registration is free and immediate.
- Have some doubt about the registration? Please read this forum article.
Explanation The above sample code is based on How to display a 2D array in GtkTreeView - Part 5 - get user selection?
What's new here:
- A global variable to know if treeview is in focus.
- Check if treeview is in focus.
- Receive key-press-event.
- Check if mouse is in header region. Please refer to How to display tooltips in GtkTreeView - Part 2? for details.
- Treeview is now out of focus.
- Process key press only when treeview is in focus.
Related Links
User reviews There are no user reviews yet. Note: You have to be a registered member to leave a comment. Free registration here. |