一个小应用

当使用GtkApplication,main主函数非常简单。我们仅仅调用了g_application_run() 并给出一个应用范例。

  1. #include <gtk/gtk.h>
  2. #include <exampleapp.h>
  3. int
  4. main (int argc, char *argv[])
  5. {
  6. return g_application_run (G_APPLICATION (example_app_new ()), argc, argv);
  7. }

所有的应用程序逻辑都在GtkApplicaton的子类中。我们的范例还没有任何有趣的功能。它所做的只是当它没有传递参数而被激活时打开一个窗口,在传递了参数被激活时打开给定的文件。

为了处理这两种情况,我们重载了activate()vfunc,当应用程序被加载没有命令行参数时它被调用,当应用程序被加载并带有命令行参数时,调用open()vfunc。

想知道更多关于GApplication入口知识,请查看GIO文档。

  1. #include <gtk/gtk.h>
  2. #include "exampleapp.h"
  3. #include "exampleappwin.h"
  4. struct _ExampleApp
  5. {
  6. GtkApplication parent;
  7. };
  8. struct _ExampleAppClass
  9. {
  10. GtkApplicationClass parent_class;
  11. };
  12. G_DEFINE_TYPE(ExampleApp, example_app, GTK_TYPE_APPLICATION);
  13. static void
  14. example_app_init (ExampleApp *app)
  15. {
  16. }
  17. static void
  18. example_app_activate (GApplication *app)
  19. {
  20. ExampleAppWindow *win;
  21. win = example_app_window_new (EXAMPLE_APP (app));
  22. gtk_window_present (GTK_WINDOW (win));
  23. }
  24. static void
  25. example_app_open (GApplication *app,
  26. GFile **files,
  27. gint n_files,
  28. const gchar *hint)
  29. {
  30. GList *windows;
  31. ExampleAppWindow *win;
  32. int i;
  33. windows = gtk_application_get_windows (GTK_APPLICATION (app));
  34. if (windows)
  35. win = EXAMPLE_APP_WINDOW (windows->data);
  36. else
  37. win = example_app_window_new (EXAMPLE_APP (app));
  38. for (i = 0; i < n_files; i++)
  39. example_app_window_open (win, files[i]);
  40. gtk_window_present (GTK_WINDOW (win));
  41. }
  42. static void
  43. example_app_class_init (ExampleAppClass *class)
  44. {
  45. G_APPLICATION_CLASS (class)->activate = example_app_activate;
  46. G_APPLICATION_CLASS (class)->open = example_app_open;
  47. }
  48. ExampleApp *
  49. example_app_new (void)
  50. {
  51. return g_object_new (EXAMPLE_APP_TYPE,
  52. "application-id", "org.gtk.exampleapp",
  53. "flags", G_APPLICATION_HANDLES_OPEN,
  54. NULL);
  55. }

应用程序中另一个受GTK+支持的重要的类是GtkApplicationWindow。它通常也是子类。我们的子类不做任何事,因此我们只得到一个空的窗口。

  1. #include "exampleapp.h"
  2. #include "exampleappwin.h"
  3. #include <gtk/gtk.h>
  4. struct _ExampleAppWindow
  5. {
  6. GtkApplicationWindow parent;
  7. };
  8. struct _ExampleAppWindowClass
  9. {
  10. GtkApplicationWindowClass parent_class;
  11. };
  12. G_DEFINE_TYPE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
  13. static void
  14. example_app_window_init (ExampleAppWindow *app)
  15. {
  16. }
  17. static void
  18. example_app_window_class_init (ExampleAppWindowClass *class)
  19. {
  20. }
  21. ExampleAppWindow *
  22. example_app_window_new (ExampleApp *app)
  23. {
  24. return g_object_new (EXAMPLE_APP_WINDOW_TYPE, "application", app, NULL);
  25. }
  26. void
  27. example_app_window_open (ExampleAppWindow *win,
  28. GFile *file)
  29. {
  30. }

作为我们应用程序初始化中的一部分,我们创建一个图标和一个桌面文件。

exampleapp.png

  1. [Desktop Entry]
  2. Type=Application
  3. Name=Example
  4. Icon=exampleapp
  5. StartupNotify=true
  6. Exec=@bindir@/exampleapp

注意 @bindir@需要被实际的二进制文件路径替代,这样桌面文件才能使用。

这就是目前我们实现的:

getting-started-app1.png

至今我们的程序并没那么瞩目,但是它已经在会话总线上出现,它有单个实例,而且它接受文件作为命令行参数。