Отображение списков. Часть 2
Сегодня в статье будет говориться о том, каким образом можно определить нажатия кнопок мыши по элементам списка и, в соответствии им, производить определённые действия.
За основу была взята программа из первой части, я только изменил содержимое списка для большей наглядности. Представим, что это у нас импровизированный файловый менеджер. В первой колонке указаны имена файлов, а во второй - их тип (папка или файл). Общепринятым правилом является при двойном щелчке левой кнопкой мыши открывать файл/папку, а при щелчке правой - показывать контекстное меню.
При нажатии любой кнопкой по элементу списка издаётся сигнал 'button-press-event':
$view->connect('button-press-event', 'on_button', $store);
function on_button($view, $event, $store)
{
Здесь мы передаём функции 'on_button' параметр $store для того, чтобы получить содержимое списка (переменные $view и $event передаются автоматически).
Содержимого выделенной строки можно получить следующим образом:
$path_array = $view->get_path_at_pos($event->x, $event->y);
$path = $path_array[0][0];
$iter = $store->get_iter($path);
$file = $store->get_value($iter, 0);
$type = $store->get_value($iter, 1);
Сначала мы определили путь ($path), потом по нему нашли элемент списка ($iter), а потом и содержимое колонок. Методу get_value() вторым параметром передаётся номер колонки. Теперь в переменной $file хранится имя выбранного файла, а в $type - тип.
При нажатии левой кнопкой мыши по элементу списка $event->button будет иметь значение 1, средней - 2, правой -3. Если произведён двойной щелчок, то $event->type будет иметь значение Gdk::_2BUTTON_PRESS. Исходя из этого напишем обработчик:
if ($event->button == 1)
{
if ($event->type == Gdk::_2BUTTON_PRESS)
echo "Двойной клик левой кнопкой\n";
else
echo "Одинарный клик левой кнопкой\n";
return FALSE;
}
elseif ($event->button == 2)
{
echo "Нажата средняя кнопка\n";
return TRUE;
}
elseif ($event->button == 3)
{
echo "Нажата правая кнопка\n";
$menu = new GtkMenu;
$menu->append(new GtkImageMenuItem(Gtk::STOCK_COPY));
$menu->append(new GtkImageMenuItem(Gtk::STOCK_CUT));
$menu->append(new GtkSeparatorMenuItem);
$menu->append(new GtkImageMenuItem(Gtk::STOCK_PASTE));
$menu->show_all();
$menu->popup();
return FALSE;
}
Для того, чтобы выбранный элемент списка получил выделение, функция on_button() должна вернуть FALSE, иначе - TRUE (что происходит при щелчке средней кнопкой). Стоит обратить внимание только на контекстное меню, открываемое при нажатии правой кнопки. О том, как его создать было рассказано в статье Программа управления веб-сервером Apache. Часть 1.
Полный код программы:
<?php
$window = new GtkWindow;
$window->set_size_request(180, 100);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
$store = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING);
$store->append(array('etc', '<DIR>'));
$store->append(array('index.html', '<FILE>'));
$store->append(array('index.php', '<FILE>'));
$view = new GtkTreeView($store);
$render = new GtkCellRendererText;
$view->append_column(new GtkTreeViewColumn('Колонка 1', $render, 'text', 0));
$view->append_column(new GtkTreeViewColumn('Колонка 2', $render, 'text', 1));
$view->connect('button-press-event', 'on_button', $store);
$scroll = new GtkScrolledWindow();
$scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
$scroll->add($view);
$window->add($scroll);
$window->show_all();
Gtk::main();
function on_button($view, $event, $store)
{
$path_array = $view->get_path_at_pos($event->x, $event->y);
$path = $path_array[0][0];
$iter = $store->get_iter($path);
$file = $store->get_value($iter, 0);
$type = $store->get_value($iter, 1);
if ($event->button == 1)
{
if ($event->type == Gdk::_2BUTTON_PRESS)
echo "Двойной клик левой кнопкой\n";
else
echo "Одинарный клик левой кнопкой\n";
return FALSE;
}
elseif ($event->button == 2)
{
echo "Нажата средняя кнопка\n";
return TRUE;
}
elseif ($event->button == 3)
{
echo "Нажата правая кнопка\n";
$menu = new GtkMenu;
$menu->append(new GtkImageMenuItem(Gtk::STOCK_COPY));
$menu->append(new GtkImageMenuItem(Gtk::STOCK_CUT));
$menu->append(new GtkSeparatorMenuItem);
$menu->append(new GtkImageMenuItem(Gtk::STOCK_PASTE));
$menu->show_all();
$menu->popup();
return FALSE;
}
}
?>
5 комментариев:
такой вопрос... а каким образом тогда можно изменить во время работы программы значение конкретной ячейки?.. Допустим, у меня создан список с одной колонкой... Возможен ли такой вариант функции для обновления этого списка?
function refresh_list()
{
global $list;
$buf=file("list.txt");
while (list($key,$value)=each($buf))
{
$list->append(array($buf[$key]));
}
}
извиняюсь, возможен... =) Только что проверил
Для обновления списка (т.е. если Вам необходимо вместо старых строчек поместить в него новые) необходимо сначала очистить модель, а потом добавлять новые значения:
$list->clear();
$list->append();
и т.д..
и такой вопрос. Как организовать выделение нескольких элементов списка?
zloiia
$store = new GtkListStore();
$tree_view = new GtkTreeView($store);
$selection = $tree_view['left']->get_selection();
$selection->set_mode(Gtk::SELECTION_MULTIPLE);
Отправить комментарий