Я программирую простой индикатор, который должен показывать значок для каждого ядра процессора на панели Unity, что изменит цвет в зависимости от температурного диапазона.C и libappindicator - Создание нескольких индикаторов
Это потребует, чтобы у меня было более одного AppIndicator в той же программе, так как я думаю, что нет никакого способа иметь один AppIndicator с несколькими значками или использовать gtk_container для их хранения и добавления в AppIndicator. Я на самом деле пытаюсь использовать 1 AppIndicator для меню (с опцией «Выход») и 1 AppIndicator для каждого ядра процессора.
В программе не было предупреждений Gtk только с одним AppIndicator (основным), но после того, как я добавил код для создания других 2 приложений для каждого ядра процессора (оба с разными уникальными идентификаторами), Gtk начал бросать некоторые предупреждения и критические Сообщения. Индикаторы отображаются на панели, как и предполагалось, но я не хочу просто игнорировать эти сообщения, поскольку они могут скрывать некоторые реальные проблемы под шторами.
Проверка кода, единственное, что я думаю, может быть запуск этих предупреждений и критических сообщений app_indicator_new()
вызывается более чем один раз, я на самом деле удалены все меню и menu_item в функции создания для этих дополнительных показателей, оставив только app_indicator_new()
вызов и Я все еще получаю эти сообщения (по одному для каждого дополнительного app_indicator_new()
вызова после первого):
(process:8040): Gtk-CRITICAL **: IA__gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8040): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8040): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
Когда я добавить код в меню создается и связанный с некоторыми дополнительными ошибками лишних AppIndicator показывают вверх:
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8681): GLib-GObject-CRITICAL **: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(process:8681): GLib-GObject-CRITICAL **: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
(process:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(process:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(process:8681): Gtk-CRITICAL **: IA__gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
(TempI:8681): Gtk-WARNING **: Screen for GtkWindow not set; you must always set
a screen for a GtkWindow before using the window
(TempI:8681): Gdk-CRITICAL **: IA__gdk_screen_get_display: assertion 'GDK_IS_SCREEN (screen)' failed
(TempI:8681): Gdk-CRITICAL **: IA__gdk_keymap_get_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
(TempI:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(TempI:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(TempI:8681): Gtk-WARNING **: Screen for GtkWindow not set; you must always set
a screen for a GtkWindow before using the window
(TempI:8681): Gdk-CRITICAL **: IA__gdk_screen_get_display: assertion 'GDK_IS_SCREEN (screen)' failed
(TempI:8681): Gdk-CRITICAL **: IA__gdk_keymap_get_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
(TempI:8681): GLib-GObject-WARNING **: invalid (NULL) pointer instance
(TempI:8681): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
При необходимости я могу выслать код программы, просто не сделал этого, потому что это поставило бы вопрос еще больше. Это блок, где я создаю дополнительные AppIndicators хотя:
for(int i=0; i<TempI_Main.Cores_Counter; i++){
TempI_Main.Core[i].Gtk_Menu_Root=gtk_menu_new();
//The core name ("Core " + number)
char IndicatorName[TEMPI_MAX_CHARS];
snprintf(IndicatorName, TEMPI_MAX_CHARS,"TempI_Core %u",i);
TempI_Main.Core[i].Gtk_Menu_Root_Description=gtk_menu_item_new_with_label(IndicatorName);
gtk_menu_append(GTK_MENU(TempI_Main.Core[i].Gtk_Menu_Root),TempI_Main.Core[i].Gtk_Menu_Root_Description);
gtk_widget_set_sensitive(GTK_WIDGET(TempI_Main.Core[i].Gtk_Menu_Root_Description),FALSE);
gtk_widget_show(TempI_Main.Core[i].Gtk_Menu_Root_Description);
TempI_Main.Core[i].Gtk_Indicator=app_indicator_new(IndicatorName,"indicator-messages",APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
app_indicator_set_status(TempI_Main.Core[i].Gtk_Indicator, APP_INDICATOR_STATUS_ACTIVE);
//Need to set icon
//Need to set attention icon
app_indicator_set_menu(TempI_Main.Core[i].Gtk_Indicator,GTK_MENU(TempI_Main.Core[i].Gtk_Menu_Root));
}
Любые подсказки, что может быть причиной? Являются ли несколько индексов приложений для каждой программы не поддерживаемыми?
EDIT:
Исправленный код после @ Жан-Франсуа Фабр ответ.
for(int i=0; i<TempI_Main.Cores_Counter; i++){
TempI_Main.Core[i].Gtk_Menu_Root=gtk_menu_new();
//The core name ("Core " + number)
char IndicatorName[TEMPI_MAX_CHARS];
//MAX_CHARS - 6 ("Core "+'\0') is the limit for appending
snprintf(IndicatorName, TEMPI_MAX_CHARS,"TempI_Core %u",i);
TempI_Main.Core[i].Gtk_Indicator_Name=strdup(IndicatorName);
TempI_Main.Core[i].Gtk_Menu_Root_Description=gtk_menu_item_new_with_label(TempI_Main.Core[i].Gtk_Indicator_Name);
gtk_menu_append(GTK_MENU(TempI_Main.Core[i].Gtk_Menu_Root),TempI_Main.Core[i].Gtk_Menu_Root_Description);
gtk_widget_set_sensitive(GTK_WIDGET(TempI_Main.Core[i].Gtk_Menu_Root_Description),FALSE);
gtk_widget_show(TempI_Main.Core[i].Gtk_Menu_Root_Description);
TempI_Main.Core[i].Gtk_Indicator=app_indicator_new(TempI_Main.Core[i].Gtk_Indicator_Name,"indicator-messages",APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
app_indicator_set_status(TempI_Main.Core[i].Gtk_Indicator, APP_INDICATOR_STATUS_ACTIVE);
//Need to set icon
//Need to set attention icon
app_indicator_set_menu(TempI_Main.Core[i].Gtk_Indicator,GTK_MENU(TempI_Main.Core[i].Gtk_Menu_Root));
}
EDIT2:
Код для создания единого основного показателя явно. Тем не менее метание предупреждение и критические сообщения:
TempI_Main.Core[0].Gtk_Menu_Root=gtk_menu_new();
TempI_Main.Core[0].Gtk_Menu_Root_Description=gtk_menu_item_new_with_label("Core1");
gtk_menu_append(GTK_MENU(TempI_Main.Core[0].Gtk_Menu_Root),TempI_Main.Core[0].Gtk_Menu_Root_Description);
gtk_widget_set_sensitive(GTK_WIDGET(TempI_Main.Core[0].Gtk_Menu_Root_Description),FALSE);
gtk_widget_show(TempI_Main.Core[0].Gtk_Menu_Root_Description);
TempI_Main.Core[0].Gtk_Indicator=app_indicator_new("Core1","indicator-messages",APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
app_indicator_set_status(TempI_Main.Core[0].Gtk_Indicator, APP_INDICATOR_STATUS_ACTIVE);
//Need to set icon
//Need to set attention icon
app_indicator_set_menu(TempI_Main.Core[0].Gtk_Indicator,GTK_MENU(TempI_Main.Core[0].Gtk_Menu_Root));
Человек, что я наделал?!? : o Спасибо, что указали это! Я создал дополнительное поле для имени «TempI_Main.Core [i] .Gtk_Indicator_Name» и использовал его вместо этого. Тем не менее, я все еще получаю предупреждения и критические сообщения. Я поставлю новый код цикла в вопросе как Редактировать! – IanC
Может ли проблема состоять в том, что куча является динамической, и строка может меняться во время выполнения программы? У libappindicator все еще был бы старый адрес и результат в том же неопределенном поведении? Я попробую использовать строковые литералы и посмотреть, каков результат. – IanC
с strdup, все должно быть в порядке. Вы уверены, что 'TEMPI_MAX_CHARS' достаточно большой? Я бы уменьшил цикл до 1 итерации: легко сделать, может пролить некоторый свет ... –