LINUX.ORG.RU

[C][GTK+] иконка из файла

 


0

1

Хочу присвоить пункту меню иконку, пока методом тыка пробовал подставлять что то вроде GTK_STOCK_EXECUTE, GTK_STOCK_GO_BACK или «gtk-dialog-info», «gtk-find». Таким образом можно выбрать любую иконку из стандартного набора, а как установить кастомную иконку из собственного файла?


gtk_icon_factory_add

Deleted
()
Ответ на: комментарий от fat_angel

Я в том смысле, что у последнего api намного проще.

fat_angel ★★★★★
()
Ответ на: комментарий от fat_angel

> Закидываешь их в /usr/share/icons/hicolor/ и вуаля

только если у тебя прав для этого достаточно и установлена hicolor-icon-theme. а ее нет в зависимостях gtk

ananas ★★★★★
()
Ответ на: комментарий от ananas

Через gtk_icon_theme_append_search_path добавляешь любой каталог к нужной теме и юзаешь их потом через gtk_icon_theme_load_icon

grassmeister
()
Ответ на: комментарий от ananas

Ну это уж как то совсем не серьезно… Прописать hicolor-icon-theme в зависимостях разрабатываемого приложения не проблема по моему. И как разработчик собирается тестировать установку своего приложения если у него нет рута?

Можно кстати создать пользовательскую тему иконок в ~/.icons, сделать ее текущей и кидать иконки туда. Только на время разработки естественно. Сам так не пробовал, но по идее должно работать. Ну и в конце-концов можно вызвать gtk_icon_theme_append_search_path()/gtk_icon_theme_prepend_search_path().

fat_angel ★★★★★
()
Ответ на: комментарий от fat_angel

> Прописать hicolor-icon-theme в зависимостях разрабатываемого приложения не проблема по моему.

кому как. добавлять лишние зависимости, когда можно обойтись без них - моветон.

И как разработчик собирается тестировать установку своего приложения если у него нет рута?


make DESTDIR=~/tmp/package.name install или подобное

к тому-же, а если мне захочется не только добавить свои, но и заменить стандартные стоковые, которые не из темы берутся, а уже встроены, типа gtk-open или gtk-ok? и скормить все это GtkBuilder-у? для работы со стоковыми изображениями в gtk предназначены классы GtkIconFactory/GtkIconSet/GtkIconSource.

ananas ★★★★★
()
Ответ на: комментарий от ananas

> кому как. добавлять лишние зависимости, когда можно обойтись без них - моветон

Если в зависимостях GTK то в любом случае можно получить указатель на дефолтную тему. По крайней мере в документации не сказано, что gtk_icon_theme_get_default() может вернуть NULL. К теме уже добавляешь нужный путь со своими иконками.

к тому-же, а если мне захочется не только добавить свои, но и заменить стандартные стоковые

Не могу представить ситуацию когда нужно менять стоковые иконки.

Погрепал исходники трех проектов - rhythmbox, empathy, gedit - везде исползуется GtkIconTheme и ни в одном GtkIconFactory

grassmeister
()
Ответ на: комментарий от grassmeister

> Если в зависимостях GTK то в любом случае можно получить указатель на дефолтную тему. По крайней мере в документации не сказано, что gtk_icon_theme_get_default() может вернуть NULL. К теме уже добавляешь нужный путь со своими иконками.

а если у меня иконки вшиты в код тем же gdk-pixbuf-csource?

ananas ★★★★★
()
Ответ на: комментарий от ananas

>а если у меня иконки вшиты в код тем же gdk-pixbuf-csource?

gdk_pixbuf_new_from_inline и gtk_icon_theme_add_builtin_icon.

Вообще я не собирался спорить о нужности/ненужности GtkIconFactory, наверное можно найти case, когда лучше будет использовать его.

Я за то, что новичку проще использовать API GtkIconTheme для установки кастомной иконки в пункт меню как заметил fat_angel.

grassmeister
()
Ответ на: комментарий от grassmeister

чем это проще, нежели gtk_icon_set_new_from_pixbuf(), gtk_icon_factory_add() - понять не могу.

сложно сказать, что новичку проще, но вот _стоковых_ элементов без factory не сделаешь.

ananas ★★★★★
()
Ответ на: комментарий от ananas

Ну давай сравним код. Задача - создать пункт меню со своей иконкой DEFAULT_ICON, находящийся в директории ICONDIR.

Мое решение с GtkIconTheme:

{
    GtkIconTheme *theme = gtk_icon_theme_get_default();
    gtk_icon_theme_append_search_path (theme, ICONDIR);
    
    GtkWidget *menu_item = gtk_image_menu_item_new_with_label ("Menu item");
    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
                                   gtk_image_new_from_icon_name (DEFAULT_ICON, 22));
}
grassmeister
()
Ответ на: комментарий от grassmeister

во-первых, не 22, а GTK_IMAGE_SIZE_MENU

во-вторых, попытайся усложнить задачу, и наклепать десяток таких пунктов, с картинками image1..image10, приведя к тому-же кусок makefile с раскладыванием картинок куда надо

ananas ★★★★★
()
Ответ на: комментарий от ananas

Пожалуйста кусок Makefile c раскидыванием иконок. А пункты меню клепаются аналогично хоть 10 хоть 100, можно вообще все меню через ui нарисовать, но мы то сравниваем два подхода загрузки иконок а не клепание меню

NULL =

private_icons_themes = \
	hicolor	\
	$(NULL)

private_icons = \
	hicolor_apps_scalable_default-icon01.svg\
	hicolor_apps_scalable_default-icon02.svg\
	hicolor_apps_scalable_default-icon03.svg\
	hicolor_apps_scalable_default-icon04.svg\
	hicolor_apps_scalable_default-icon05.svg\
	hicolor_apps_scalable_default-icon06.svg\
	hicolor_apps_scalable_default-icon07.svg\
	hicolor_apps_scalable_default-icon08.svg\
	hicolor_apps_scalable_default-icon09.svg\
	hicolor_apps_scalable_default-icon10.svg\
	$(NULL)

EXTRA_DIST = \
	$(private_icons)	\
	$(NULL)

###############################################################################

gtk_update_icon_cache = gtk-update-icon-cache -f -t

update-icon-cache:
	@-if test -z "$(DESTDIR)"; then \
		echo "Updating Gtk icon cache."; \
		for theme in $(private_icons_themes); do \
			$(gtk_update_icon_cache) $(pkgdatadir)/icons/$$theme; \
		done; \
	else \
		echo "*** Icon cache not updated.  After (un)install, run this:"; \
		for theme in $(private_icons_themes); do \
			echo "***   $(gtk_update_icon_cache) $(pkgdatadir)/icons/$$theme"; \
		done; \
	fi

install-icons:
	for icon in $(private_icons); do \
		THEME=`echo $$icon | cut -d_ -f1`; \
		CONTEXT=`echo $$icon | cut -d_ -f2`; \
		SIZE=`echo $$icon | cut -d_ -f3`; \
		ICONFILE=`echo $$icon | cut -d_ -f4`; \
		mkdir -p $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT; \
		$(INSTALL_DATA) $(srcdir)/$$icon $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \
	done

uninstall-icons:
	for icon in $(private_icons); do \
		THEME=`echo $$icon | cut -d_ -f1`; \
		CONTEXT=`echo $$icon | cut -d_ -f2`; \
		SIZE=`echo $$icon | cut -d_ -f3`; \
		ICONFILE=`echo $$icon | cut -d_ -f4`; \
		rm -f $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \
	done

install-data-local: install-icons update-icon-cache

uninstall-local: uninstall-icons update-icon-cache

Давайте свой код все таки с GtkconFactory

grassmeister
()
Ответ на: комментарий от grassmeister

во-первых, ты схитрил. при чем тут .svg? .png давай, нефиг лишние зависимости тянуть. во-вторых, все-же, где код для остальных элементов, склепаный по китайской технологии cut-n-paste? и до купы туда же добавить пяток этих-же элементов для тулбара, да с акселераторами. слабо?

что касается кода

#include "pixmaps.h"
... 
static GtkStockItem stock_items[] = {       
  {"item1", "Item 1", 0, 0, NULL},                      
  ...
  {"item10", "Item 10", 0, 0, NULL},  
}; 
...

#define add_icon(f,d,s) \
do { \
  GtkIconSet *set; \
  GdkPixbuf *pb = gdk_pixbuf_new_from_inline(-1, d, FALSE, NULL); \
  set = gtk_icon_set_new_from_pixbuf(pb); \
  g_object_unref(pb); \
  gtk_icon_factory_add(f, s, set); \
  gtk_icon_set_unref(set); \
} while (0)
...
GtkIconFactory *factory = gtk_icon_factory_new ();
add_icon(factory, item1, "item1");
...
add_icon(factory, item10, "item10");  
gtk_icon_factory_add_default(factory);
gtk_stock_add_static(stock_items, G_N_ELEMENTS(stock_items));
...

дальше я могу клепать все, что угодно, хоть элементы меню, хоть кнопки, хоть чего простым дерганьем соответственного gtk_*_from_stock(). причем никаких обращений к диску для считывания картинок не будет, да и на смену темы я тоже плевал, мне ее уже отслеживать не надо

да и в makefile будет одно простое правило

LIST = item1 item1.png \
...
       item10 item10.png \

pixmaps.h:
     gdk--pixbuf-csource --raw --build-list $(LIST) >../pixmaps.h
ananas ★★★★★
()
Ответ на: комментарий от ananas

Во-первых: Svg для того чтобы нормально генерировать иконки разных размеров, если для вас принципиально убрать loader для svg из зависимостей gdk-pixbuf, то можно добавить в Makefile строчки генерирующие png нужных размеров.

Во-вторых: в случае с темой - тема кэширует иконки, поэтому иконка читается один раз при первом обращении,и в отличие от вашего варианта ненужная иконка не висит в памяти с момента старта программы, что критично если у тебя набор из 40+ иконок причем разных размеров - для меню, маленького тулбара, гигантского тулбара, кнопок и т.д.

В-третих: китайский код как раз будет в вашем случае если нужно добавить более 100 иконок. Причем надо отметить, что иконки для тулбара и меню могут быть опять же разного размера. Еще и разворачивание макроса для каждой из них.

В четвертых: тему вам все таки отслеживать придется, потому что смена темы перепишет ваши стоковые иконки. Смотрите кусок документации на GtkIconfactory:

gtk_icon_factory_add

....Themes can provide an icon with the same name (such as «myapp-whatever-icon») to override your application's default icons. If an icon already existed in factory for stock_id, it is unreferenced and replaced with the new icon_set.

В пятых:ваш код субъективно сложнее и больше, требует отдельной инициализации при старте, да еще и макрос зачем то там где можно функцию использовать. Как все это отлаживать потом будете и тестировать?

В шестых: меню и тулбары я опишу таки в .ui файле, а не копипастой.

grassmeister
()
Ответ на: комментарий от grassmeister

1. добавьте. правила разбухнут до невозможности

2. в случае смены темы кэш слетает. к тому-же, чтение все равно происходит, в случае 40+ иконок это будет 40+ раз, если не в разы больше, учитывая разные размеры иконок для разных элементов ui.

3. еще раз - добавь 40+ gtk_image_menu_item_new_with_label()/gtk_image_menu_item_set_image()/gtk_image_new_from_icon_name(), и сравни с 40+ gtk_image_menu_item_new_from_stock()

4. в случае уникальных имен не придется

5. субъективность - дело такое

6. GtkUIManager и GtkBuilder сейчас не обсуждаются. понятно, что с ними проще, и в этом случае действительно более выгодно держать иконки в теме

ananas ★★★★★
()
Ответ на: комментарий от ananas

Ладно, дискуссия перешла в спор о том какие гандоны лучше - с пупырышками или с ребрышками.

Каждый использует, то что считает подходящим для своих целей.

ЗЫ: Спасибо тебе дядька ананас, напомнил про обработку события смены темы. Добавил себе тикет.

grassmeister
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.