gpt4 book ai didi

C 和 libappindicator - 创建多个指标

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:37 25 4
gpt4 key购买 nike

我正在编写一个简单的指示器,它应该为 Unity 面板中的每个 CPU 内核显示一个图标,该图标会根据温度范围改变颜色。

这将要求我在同一个程序上有多个 AppIndicator,因为我认为没有办法让一个 AppIndicator 具有多个图标或使用 gtk_container 来保存这些图标并将其附加到 AppIndicator。我实际上正在尝试为菜单使用 1 个 AppIndicator(带有“退出”选项),为每个 CPU 核心使用 1 个 AppIndicator。

该程序只有一个 AppIndicator(主要的)没有 Gtk 警告,但在我添加了为每个 CPU 核心创建其他 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 的 block :

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));
}

任何线索可能是什么原因? 每个程序是否不支持多个 AppIndicators

编辑:

@Jean-François Fabre 回答后更正了代码。

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));
}

编辑 2:

用于显式创建单个核心指标的代码。仍然抛出警告和关键信息:

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));

最佳答案

在一个循环中是很糟糕的:

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);
...
TempI_Main.Core[i].Gtk_Indicator=app_indicator_new(IndicatorName, ...

您将 IndicatorName 声明为循环中的自动变量,但将其传递给需要 const char *gtk_menu_item_new_with_label,这意味着:它将只存储字符串的地址。

不仅内存将被重新用于进一步的迭代,而且所有菜单在循环中都将具有相同的指示器名称,但退出循环时内存将被分配给其他一些变量,名称将被丢弃=>未定义的行为

您应该像这样制作字符串的副本:

TempI_Main.Core[i].Gtk_Menu_Root_Description=gtk_menu_item_new_with_label(strdup(IndicatorName));

(当然,更好的方法是存储复制的字符串以便在需要时能够释放它们)

关于C 和 libappindicator - 创建多个指标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39498940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com