Отправляет email-рассылки с помощью сервиса Sendsay

Практические советы по GTK+

  Все выпуски  

Практические советы по GTK+ Image Viewer 1.8



Image Viewer 1.8

После летнего перерыва продолжаем писать GTK приложение для просмотра графических файлов.
Сегодня рассмотрим новое окно - область предосмотра картинок.
Добавим новый файл в проект: pictures_preview.c

На сегодня новый виджет - GtkIconView, который  отображает список иконок.  Вот основная функция, которая создаёт область просмотра иконок:

enum
{
    COL_PATH,
    COL_DISPLAY_NAME,
    COL_PIXBUF,
    COL_IS_DIRECTORY,
    NUM_COLS
};

// Создание окна с предварительным просмотром картинок
GtkWidget* create_pictures_preview(void)
{
    GtkWidget *vbox;
    GtkWidget *toolbar;
    GtkWidget *sw;
    GtkWidget *icon_view;
    // размеры иконок для тулбара
    GtkIconSize icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;// GTK_ICON_SIZE_LARGE_TOOLBAR;

    // вертикальный контейнер
    vbox = gtk_vbox_new (FALSE, 0);
    gtk_widget_set_size_request (vbox, 10, -1);//set a minimum size

    // создаём тулбар
    toolbar = gtk_toolbar_new ();
    gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar),icon_size);
    gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
    // кнопки для тулбара
    back_button = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), back_button, -1);
    up_button = gtk_tool_button_new_from_stock (GTK_STOCK_GO_UP);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), up_button, -1);
    home_button = gtk_tool_button_new_from_stock (GTK_STOCK_HOME);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), home_button, -1);

    // Делаем кнопку "назад" пока недоступной
    gtk_widget_set_sensitive (GTK_WIDGET (back_button), FALSE);
    // Делаем кнопку "вверх" пока недоступной
    gtk_widget_set_sensitive (GTK_WIDGET (up_button), FALSE);

    // создать область прокрутки
    sw = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),GTK_SHADOW_ETCHED_IN);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
   
    // стартовый каталог для просмотра
    dir_parent = g_strdup ("/");
    // Создать список
    store = gtk_list_store_new(    NUM_COLS,            // всего 4 элемента в списке
                                G_TYPE_STRING,        // 1 - строка (путь к файлу)
                                G_TYPE_STRING,        // 2 - строка (имя файла в кодировке UTF8)
                                GDK_TYPE_PIXBUF,    // 3 - картинка (иконка файла)
                                G_TYPE_BOOLEAN);    // 4 - булевая (регулярный файл или каталог)
    // заполнить список иконок
    fill_store (store);
    // создать область вывода иконок на экран
    icon_view = gtk_icon_view_new_with_model(GTK_TREE_MODEL (store));
    //gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),GTK_SELECTION_MULTIPLE);
    gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), COL_DISPLAY_NAME);
    gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), COL_PIXBUF);
    g_object_unref (store);
   
    // упаковка
    gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
    gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
    gtk_container_add (GTK_CONTAINER (sw), icon_view);// упаковать в область прокрутки

    // подключение обработчиков
    // для кнопки "назад" подключаем обработчик к сигналу "clicked"-нажатие
    g_signal_connect (back_button, "clicked",G_CALLBACK (back_clicked),NULL);
    // для кнопки "вверх" подключаем обработчик к сигналу "clicked"-нажатие
    g_signal_connect (up_button, "clicked",G_CALLBACK (up_clicked),NULL);
    // для кнопки "домой" подключаем обработчик к сигналу "clicked"-нажатие
    g_signal_connect (home_button, "clicked",G_CALLBACK (home_clicked),NULL);
    // для облаcти вывода иконок подключаем обработчик к сигналу "item_activated"-выбран элемент
    g_signal_connect (icon_view, "item-activated",G_CALLBACK (item_activated), store);
    g_signal_connect (icon_view, "selection-changed",G_CALLBACK (selection_changed), store);
   
   
    return vbox;
}

Сверху будет небольшое меню - Toolbar, в котором будут три кнопки - назад, вверх и домой, а снизу область просмотра иконок,
которая создаётся функцией gtk_icon_view_new_with_model.В предварительно созданном списке store будем хранить 4 элемента:
путь к файлу в кодировке системы (для обращения к файлам),
имя файла в кодировке UTF8 (для отображения на экран),
битовый образ картинки (GdkPixbuf),
метку - файл это или каталог.
Для заполнения списка store сначала нужно добавить новый элемент в список:
gtk_list_store_append (store, &iter);

а потом заполнить этот элемент:

gtk_list_store_set (store, &iter,
                            COL_PATH, path, // путь к файлу в кодировке системы (для обращения к файлам)
                            COL_DISPLAY_NAME, display_name, // имя файла в кодировке UTF8 (для отображения на экран)
                            COL_IS_DIRECTORY, is_dir, // метка - файл это или каталог.
                            COL_PIXBUF, is_dir ? folder_pixbuf : file_pixbuf, // битовый образ картинки или папки (GdkPixbuf)
                            -1);

Для удаления всех элементов списка используем gtk_list_store_clear (store);
Более подробно можно посмотреть в исходных кодах.

Получился полноценный мини-просмоторщик графических файлов, созданный с минимальными усилиями, при этом использовались только стандартные элементы GTK+. По моему, самым большим недостатком приложения является заметно длительное открытие каталогов с большим числом графических файлов, хотя это можно просто исправить, оптимизировав загрузку нескольких изображений подряд, а также перенести загрузку иконок для всех картинок из каталога в отдельный поток. Кстати, в Glib есть функции для работы с потоками, так что Ваше многопоточное приложение может работать в разных операционных системах без изменения исходных кодов.

Готовое приложение + исходные коды доступны по ссылке: image-viewer1.8.tar.gz [23 кб]

Все вопросы, замечания и пожелания можно отсылать по адресу: comp.soft.prog.gtk-owner@subscribe.ru




В избранное