You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C++正确构建Gtk系统托盘?

构建GTK系统托盘的完整正确流程

注:GtkStatusIcon是构建系统托盘的经典实现方式(GTK 3.24+已标记为弃用,若需适配新版GTK,推荐使用Gio桌面应用API),以下基于传统GtkStatusIcon完成完整流程。

1. 基础初始化与主窗口设置

首先初始化GTK环境,创建主窗口(系统托盘程序默认隐藏主窗口,仅在用户触发时显示):

#include <gtk/gtk.h>

// 声明回调函数
void trayView(GtkMenuItem *item, gpointer window);
void trayExit(GtkMenuItem *item, gpointer data);
void trayPopupMenu(GtkStatusIcon *icon, guint button, guint activate_time, gpointer menu);

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    // 创建主窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "GtkStatusIcon Example");
    gtk_widget_set_size_request(window, 200, 200);
    // 默认隐藏主窗口
    gtk_widget_hide(window);
    // 绑定窗口关闭事件:点击叉号时隐藏窗口而非退出程序
    g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);

2. 创建系统托盘图标

通过本地图片文件生成托盘图标,同时设置鼠标悬停提示:

// 从本地文件创建托盘图标
    GtkStatusIcon *trayIcon = gtk_status_icon_new_from_file("/root/Desktop/icon.png");
    // 确保托盘图标可见
    gtk_status_icon_set_visible(trayIcon, TRUE);
    // 设置鼠标悬停时的提示文本
    gtk_status_icon_set_tooltip_text(trayIcon, "GTK系统托盘示例");

3. 构建右键弹出菜单

创建菜单及菜单项,绑定对应的功能回调:

// 创建右键菜单容器
    GtkWidget *menu = gtk_menu_new();
    // 创建菜单项
    GtkWidget *menuItemView = gtk_menu_item_new_with_label("显示窗口");
    GtkWidget *menuItemExit = gtk_menu_item_new_with_label("退出程序");

    // 绑定菜单项的激活回调
    g_signal_connect(G_OBJECT(menuItemView), "activate", G_CALLBACK(trayView), window);
    g_signal_connect(G_OBJECT(menuItemExit), "activate", G_CALLBACK(trayExit), NULL);

    // 将菜单项添加到菜单
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItemView);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItemExit);
    // 显示所有菜单项
    gtk_widget_show_all(menu);

4. 关联托盘图标与右键菜单

绑定托盘图标的右键点击信号,触发菜单弹出:

// 绑定托盘图标右键点击事件(button=3对应鼠标右键)
    g_signal_connect(G_OBJECT(trayIcon), "popup-menu", G_CALLBACK(trayPopupMenu), menu);

5. 实现回调函数逻辑

完成菜单项和菜单弹出的具体功能:

// 启动GTK主事件循环
    gtk_main();
    return 0;
}

// 显示/隐藏主窗口的回调函数
void trayView(GtkMenuItem *item, gpointer window)
{
    if (gtk_widget_get_visible(GTK_WIDGET(window))) {
        gtk_widget_hide(GTK_WIDGET(window));
    } else {
        gtk_widget_show(GTK_WIDGET(window));
        gtk_window_present(GTK_WINDOW(window)); // 将窗口前置显示
    }
}

// 退出程序的回调函数
void trayExit(GtkMenuItem *item, gpointer data)
{
    gtk_main_quit();
}

// 弹出右键菜单的回调函数
void trayPopupMenu(GtkStatusIcon *icon, guint button, guint activate_time, gpointer menu)
{
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, gtk_status_icon_position_menu, icon, button, activate_time);
}

编译与运行

假设代码文件名为tray.cpp,使用以下命令编译:

# 适配GTK2
g++ tray.cpp -o gtk-tray `pkg-config --cflags --libs gtk+-2.0`
# 适配GTK3(注意GtkStatusIcon在GTK3.24+已弃用)
g++ tray.cpp -o gtk-tray `pkg-config --cflags --libs gtk+-3.0`

运行编译后的程序:

./gtk-tray

关键注意事项

  • 图标路径:确保图标文件路径正确,使用相对路径时需注意程序运行的工作目录
  • GTK版本兼容:GtkStatusIcon在GTK3.24+已被标记为弃用,若需适配新版GTK,建议基于Freedesktop桌面规范实现
  • 窗口行为:主窗口绑定gtk_widget_hide_on_delete,避免用户关闭窗口时直接退出整个程序

内容的提问来源于stack exchange,提问作者Rushikersh Office

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:06:24