我正在編程一個簡單的指示器,它應該顯示Unity面板中每個CPU Core的圖標,它將根據溫度範圍改變顏色。C和libappindicator - 創建多個指示器
這將需要我在同一個程序上有多個AppIndicator,因爲我認爲沒有辦法讓一個AppIndicator具有多個圖標或使用gtk_container來保存這些圖標並將其附加到AppIndicator。實際上,我嘗試使用1個AppIndicator作爲菜單(帶有「退出」選項)和1個AppIndicator用於每個CPU核心。
該程序沒有Gtk警告只有一個AppIndicator(主要的),但是當我添加了用於爲每個CPU Core創建其他2個AppIndicator的代碼(兩個都有不同的唯一ID)後,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));
}
任何線索可能是什麼原因? 每個程序是否支持多個AppIndicator?
編輯:
更正代碼之後@讓 - 弗朗索瓦·法布爾的答案。
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次迭代:容易做到,可能會減少一些光... –