GtkApplication和gtk_init有什么区别?

8

我现在正在学习在Linux中使用C语言和GTK+3.0。在阅读了一些教程和示例代码之后,我有一些关于如何初始化应用程序的问题。

这里有两个版本的代码:

#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

这段代码使用gtk_application_new()来初始化一个GtkApplication,并使用g_application_run()来启动它。

这是第二个。

#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),"helloworld");
  gtk_widget_show(window);
  gtk_main();

  return 0;
}

这段代码使用 gtk_init() 来初始化应用程序,使用 gtk_main() 来运行它。

然而,我无法弄清它们之间的区别,因为运行结果似乎相同。


我看到了巨大的差异。我在Macbook Air 5,2上运行Linux commandos 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) x86_64 GNU/Linux。第一个示例立即加载,而第二个示例需要约30秒才能加载。 - Deanie
3个回答

4
gtk_init()函数初始化库使用的内部变量,g_application_new()在内部调用gtk_init(),所以它们之间没有区别或相似之处,它们具有不同的目的,只是其中一个包含另一个。

我并非从文档或类似的内容中了解这个信息,这只是一个逻辑上的结论。

可能是为了避免在Gtk+库中使用全局变量,创建了GtkApplication,现在你可以使用GtkApplication来保存应用程序范围内的变量。

因此,看起来这是正确的方法,我个人很喜欢它,但我已经很久没有写过Gtk+应用程序了,而且当时是使用版本2,所以我对它不太了解。

Gtk+有一个很棒的功能,就是它的文档非常完善,只需搜索GtkApplication,您就能更好地理解它的用途以及如何使用它。


我注意到如果我使用第二种方法,我不会得到一个 GtkApplication 变量。这对进一步编码有影响吗? - zhshr
而且你提到它们有不同的用途。在这种情况下,如果我想编写一个应用程序,我应该使用哪个? - zhshr
这取决于你想要构建什么,GtkApplication 可能有用也可能没用,但我认为它是 Gtk+3 中的一种新方法,在之前的版本中不存在,它采用了更面向对象的方法,因为 Glib 采用了面向对象的方法。所以我认为你应该选择 GtkApplication,以避免未来的兼容性问题。 - Iharob Al Asimi
GtkApplication 和它的基类 GApplication 不仅仅是避免全局变量那么简单... - underscore_d
@underscore_d 当然,但是 gtk_init() 会创建一个应用程序全局状态,我认为这些是静态全局变量,有很多缺点。我希望也有类似的 CURL_APP。我自己总是创建一个全局上下文对象,该对象将在函数之间传递以执行许多操作,并避免使用全局状态,因为你知道,像那样在堆上分配的上下文并不真正是全局的。 - Iharob Al Asimi

3
请查看GtkApplication文档GtkApplication类处理应用程序的初始化、生命周期、主窗口、全局资源等。如果您不想使用它,那没问题,但是如果您需要这些功能,您将不得不手动完成所有这些事情。
这包括初始化Gtk:即调用gtk_init()

0
  1. GtkApplication 引入了动作支持,您可以使用动作来解耦可操作项(如菜单、按钮等)和相应的回调函数。
  2. 您可以使用 g_application_send_notification 来显示通知,并替换已弃用的 GtkStatusIcon
  3. 您可以使用命令行在现有应用程序中打开文件:https://developer.gnome.org/gio/stable/GApplication.html#GApplication-open

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接