【问题标题】:Gtk+3 &C & Glade problemsGtk+3 &C & Glade 问题
【发布时间】:2017-08-18 09:17:23
【问题描述】:

我尝试在 Linux 上使用 C 和 Glade 制作一个简单的 Gui 程序。 我写了一个简单的程序并用 Glade 设计了一个窗口。 当我运行代码时,它说:

(gtk-test:23026): Gtk-CRITICAL **: gtk_widget_show: assertion ‘GTK_IS_WIDGET(widget)’ failed

而且没有打开任何窗口。 我在互联网上搜索了一下,但没有任何帮助。有人说我必须将 glade 文件转换为 .xml,但这没有用。

C

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    GtkBuilder      *builder; 
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "window_main.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);

    g_object_unref(builder);

    gtk_widget_show(window);                
    gtk_main();

    return 0;
}

void on_window_main_destroy()
{
    gtk_main_quit();
}

林间空地

<?xml version=1.0 encoding="UFT-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
    <requires lib="gtk+" version="3.12"/>
    <object class="GtkWindow" id="window_main">
        <property name="can_focus">False</property>
        <property name="title" translatable="yes">Test Window</property>
        <property name="default_width">640</property>
        <property name="default_height">480</property>
        <signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
        <child>
            <placeholder/>
        </child>
    </object>
</interface>

【问题讨论】:

  • UFT -=> UTF
  • 正如José所说,一旦你加载了没有GError的文件,你还应该检查gtk_builder_get_object()的返回值是否为NULL,表示失败查找,当然会无法断言它是有效的GtkWidget *。在这种情况下,它可能会失败,因为文件根本没有成功加载,但您至少应该验证查找是否成功,至少在您巩固 .ui 文件的结构并知道它总是会成功之前。错误检查的存在是有原因的 - 不要只是推倒它并期望一切正常。
  • 我将使用 GError 示例和@underscore_d 正确指示检查结果 og builder 获取对象函数/方法来更新答案。

标签: c linux gtk3 glade


【解决方案1】:

您似乎手动添加了 xml 标记,它的格式不正确。同时,您没有对 gtk_builder_add_from_file 函数进行任何错误检查。

您的 xml 开头为:

<?xml version=1.0 encoding=UFT-8>

应该是:

<?xml version="1.0" encoding="UTF-8"?>

为避免这种情况,您应该使用 GError 并检查使用 gtk_builder_add_from_file 解析构建器文件时是否有错误。

编辑:

我看到您已更新问题中的 glade 文件。如果你这样做,那么答案可能并不明显。无论如何,这是您的代码,其中包含检查 glade 文件是否存在的错误和 @underscore_d 检查 GtkBuilder get_object 函数的提示(可以改用 g_assert 宏):

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    GError          *err = NULL;
    GtkBuilder      *builder; 
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "window_main.glade", &err);

    if (err != NULL) {
        fprintf (stderr, "Unable to read file: %s\n", err->message);
        g_error_free(err);
        return 1;
    }

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));

    if (window == NULL || !GTK_IS_WINDOW(window)) {
        fprintf (stderr, "Unable to get window. (window == NULL || window != GtkWindow)\n");
        return 1;
    }

    gtk_builder_connect_signals(builder, NULL);

    g_object_unref(builder);

    gtk_widget_show(window);                
    gtk_main();

    return 0;
}

void on_window_main_destroy(GtkWidget *widget, gpointer user_data)
{
    gtk_main_quit();
}

编译:

gcc -rdynamic -o window main.c `pkg-config --cflags --libs gtk+-3.0`

【讨论】:

  • 是的,我是手动添加的,因为我现在只有打印出来。
  • 我是 gtk 的新手,所以我不知道 GError 是什么意思。你能为我解释一下吗?
  • 他们也不检查gtk_builder_get_object() 的返回值是否为NULL,这表明查找失败,当然也无法断言它是有效的GtkWidget *
  • 它抱怨是因为信号处理程序on_window_main_destroy 不在main.c 上。 -rdynamic 它是需要的 gcc 标志,因为您在 glade xml 中定义了信号处理程序。我将编辑答案以添加信号处理程序。是的,您可以将 -rdynamic 添加到 gcc,但目标只是验证您遇到的具体问题。关于日食,这是另一个问题,不确定我能帮助你。我不使用 eclipse,它特定于 eclipse 调用编译器等的方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多