gtk使用ui文件定义界面运行报错

今天在照着gtk的官方教程做示例的时候,遇到一个问题,就是下面的链接,https://docs.gtk.org/gtk4/getting_started.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <gtk/gtk.h>
#include <glib/gstdio.h>

static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}

static void
quit_cb (GtkWindow *window)
{
gtk_window_close (window);
}

static void
activate (GtkApplication *app,
gpointer user_data)
{
/* Construct a GtkBuilder instance and load our UI description */
GtkBuilder *builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "builder.ui", NULL);

/* Connect signal handlers to the constructed widgets. */
GObject *window = gtk_builder_get_object (builder, "window");
gtk_window_set_application (GTK_WINDOW (window), app);

GObject *button = gtk_builder_get_object (builder, "button1");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);

button = gtk_builder_get_object (builder, "button2");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);

button = gtk_builder_get_object (builder, "quit");
g_signal_connect_swapped (button, "clicked", G_CALLBACK (quit_cb), window);

gtk_widget_set_visible (GTK_WIDGET (window), TRUE);

/* We do not need the builder any more */
g_object_unref (builder);
}

int
main (int argc,
char *argv[])
{
#ifdef GTK_SRCDIR
g_chdir (GTK_SRCDIR);
#endif

GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);

int status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);

return status;
}

官方给的代码,没有说builder.ui这个文件放在哪里,我就放到了和main.c同级的子目录下,结果编译能通过,但是运行时报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(main.exe:53272): Gtk-CRITICAL **: 23:14:02.343: gtk_window_set_application: assertion 'GTK_IS_WINDOW (window)' failed

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.348: invalid (NULL) pointer instance

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.351: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.356: invalid (NULL) pointer instance

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.360: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.364: invalid (NULL) pointer instance

(main.exe:53272): GLib-GObject-CRITICAL **: 23:14:02.367: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(main.exe:53272): Gtk-CRITICAL **: 23:14:02.372: gtk_widget_set_visible: assertion 'GTK_IS_WIDGET (widget)' failed

由于刚开始学,也不太会调试,完全没有头绪。但是编译能通过,觉得代码应该是没问题的。就猜,可能是ui文件路径不对。就试着改了两下,最后试出来了,gtk_builder_add_from_file (builder, "builder.ui", NULL); 这句中的builder.ui应该写这个项目中的相对路径,或是绝对路径。我放到了项目目录的src文件夹下,用相对路径写法,应该写成gtk_builder_add_from_file (builder, "src/builder.ui", NULL);,再次make run,就不再报错了。

如果这个以后想换个位置也能运行,这个ui文件应该放到另外的一个目录下,到时再研究怎么发布exe吧。