开发环境搭建
- Ubuntu 14 Desktop
- Lib GTK3
- Lib Appindicator3
GTK3开发环境安装:
sudo apt-get install libgtk-3-dev make gcc pkg-config
托盘图标开发包安装:
sudo apt-get install -y libappindicator3-dev
GTK Hello World!
首先我们来尝试一下由GTK程序的Hello World,创建一个标题为"Window" 的GTK窗口
#include <gtk/gtk.h>
int main (int argc, char *argv[]){
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Window");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show (window);
gtk_main ();
return 0;
}
程序编译
sudo gcc `pkg-config --cflags gtk+-3.0` hello.c -o hello `pkg-config --libs gtk+-3.0`
普通用户编译可能会造成 (.text+0x18):对‘main’未定义的引用 错误
到这里我们已经证明了我们的开发环境已经可用。
托盘程序
我们需要创建一个如下的状态栏图标程序:
托盘程序使用GTK和appindicator3 API实现,使用GTK创建UI主程序和提供菜单,使用libappindicator 创建状态栏的图标。
main.c 示例代码如下:
#include <stdio.h>
#include <gtk/gtk.h>
#include <libappindicator/app-indicator.h>
#include <string.h>
#define APPINDICATOR_ID "MyFirstTrayApp"
#define ICON "/tmp/tmp.MV7CyDttpW/cmake-build-debug/icon.ico"
GtkMenuShell *create_menu();
int main() {
AppIndicator *indicator = NULL;
GtkMenuShell *indicator_menu = NULL;
if (gtk_init_check(0, NULL) == FALSE) {
return -1;
}
indicator = app_indicator_new(APPINDICATOR_ID, ICON,
APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE);
app_indicator_set_icon(indicator, ICON);
indicator_menu = create_menu();
app_indicator_set_menu(indicator, GTK_MENU (indicator_menu));
gtk_main();
return 0;
}
void hello_cb(GtkMenuItem *item, gpointer data) {
printf(">> Hello world!\n");
}
GtkMenuShell *create_menu() {
GtkWidget *hello_item;
GtkWidget *quit_item;
GtkMenuShell *indicator_menu;
indicator_menu = (GtkMenuShell *) gtk_menu_new();
hello_item = gtk_check_menu_item_new_with_label("你好!");
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(hello_item), FALSE);
gtk_widget_set_sensitive(hello_item, TRUE);
g_signal_connect(hello_item, "activate", G_CALLBACK(hello_cb), NULL);
quit_item = gtk_check_menu_item_new_with_label("退出");
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(quit_item), FALSE);
gtk_widget_set_sensitive(quit_item, TRUE);
g_signal_connect(quit_item, "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(hello_item);
gtk_widget_show(quit_item);
gtk_menu_shell_append(indicator_menu, hello_item);
gtk_menu_shell_append(indicator_menu, quit_item);
return indicator_menu;
}
注意:图标文件名必须要是绝对路径,否则图标无法显示!
- 初始GTK。
- 使用Appindicator3 API 创建并初始化Appindicator。
- 使用GTK创建菜单,并把菜单关联到Appindicator,菜单包含两个功能,控制台打印字符串、退出程序。
- 启动程序。
编译程序
sudo gcc `pkg-config --cflags gtk+-3.0 appindicator3-0.1` main.c -o main `pkg-config --libs gtk+-3.0 appindicator3-0.1`
运行程序
CMake进行项目管理
CMake可以非常方便的对C/C++工程进行管理,减少编译连接对开发者的负担,使用上面程序作为工程文件,创建一个CMake项目。
首先,安装CMake:
sudo apt-get install cmake
- 创建目录
UbuntuTray - 把刚才创建的
main.c 和icon.ico 文件复制到目录中。 - 创建
CMakeLists.txt
如下所示:
CMakeLists.txt内容:
cmake_minimum_required(VERSION 2.8)
project(UbuntuTray C)
set(CMAKE_C_STANDARD 99)
add_executable(main main.c)
如果是一个普通程序,那么上面内容表示生成编译生成一个名为main 的可执行程序。
由于我们的程序使用到了gtk+-3.0 、appindicator3 两个库,编译时使用需要指明头文件位置,连接时需要指明需要连接的动态库。
之前gcc编译命令中,我们使用pkg-config 程序来查找这2个库的头文件(pkg-config --cflags 参数)和动态库(pkg-config --libs 参数)。
在CMake中我们需要使用下面语法来进行查找和使用
完整的CMakeLists.txt内容:
cmake_minimum_required(VERSION 2.8)
project(UbuntuTray C)
set(CMAKE_C_STANDARD 99)
# pkg-config --cflags gtk+-3.0 appindicator3-0.1
# pkg-config --libs gtk+-3.0 appindicator3-0.1
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(AppI3 REQUIRED appindicator3-0.1)
# 添加头文件目录
include_directories(${GTK3_INCLUDE_DIRS} ${AppI3_INCLUDE_DIRS})
# 添加链接库目录
link_directories(${GTK3_LINK_LIBRARIES} ${AppI3_LINK_LIBRARIES})
add_executable(main main.c)
# 可执行程序链接库
target_link_libraries(main ${GTK3_LIBRARIES} ${AppI3_LIBRARIES})
- 首先使用
find_package(PkgConfig REQUIRED) 引入pkg-config ,请确保已经在系统中安装pkg-config 。 - 使用
pkg_check_modules(变量名 REQUIRED 包名称) 查找相关的模块,如果模块存在那么会以变量名 作为前缀设置一些列的变量,如:头文件路径 _INCLUDE_DIRS 、依赖包_LIBRARIES 。 - 接下来添加使用之前设置变量来添加头文件和链接库的目录。
- 最后为可执行程序链接冬天库。
创建用于构建的目录,并运行cmake构建Makefile等相关文件
mkdir build
cd build/
cmake ..
运行后会在build目录生成构建相关的文件
可以看到已经生成了Makefile,我们接下来我们使用make命令编译程序即可:
make
可以看到我们的main 可执行程序已经编译完成
运行程序可以看到与我们之前使用gcc命令编译的程序一样效果。
参考文献
[1]. ubuntu . ApplicationIndicators . https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators [2]. gtk . gtk3 . https://docs.gtk.org/gtk3/ [3]. 博客园 . 用cmake构建gtk程序 . ChrisZZ . 2019.06 . https://www.cnblogs.com/zjutzz/p/10959211.html [4]. 空心菜 . cmake使用pkg-config配置工程依赖 . 2021.03 . https://kxcblog.com/post/dev/cmake-pkg-config/ [5]. github . Serge Zaitsev . zserge/tray . https://github.com/zserge/tray [6]. github getlantern . getlantern/systray . https://github.com/getlantern/systray
|