4

我用模板创建了一个自定义 Gtk Widget,我想在其他 Gtk Builder 文件中使用它。

我做了什么:

  • 写了一个 .ui 文件<template class="G3JAMinScenes" parent="GtkBox">
  • 编写小部件源代码 (.c/.h)

当我使用g3jamin_scenes_new小部件按预期创建它时,问题是我想使用 Gtk Builder 将它添加为窗口的子窗口,所以我写道:

...
<child>
    <object class="G3JAMinScenes" parent="GtkBox" id="scnes">
    </object>
</child>
...

但是当我尝试运行时它会引发错误:

Gtk-CRITICAL **: Error building template class 'G3JAMinAppWindow' for an instance of type 'G3JAMinAppWindow': Invalid object type `G3JAMinScenes'
4

1 回答 1

4

我无法在任何文档中找到任何官方答案。我去挖掘了 GTK+ 源代码,发现了一些东西。

GtkBuilder看到一个它还不知道的类型时,它会尝试获取一个返回相关的函数GType。它将尝试一些启发式方法来确定要调用的函数。如果您使用的G_DEFINE_TYPE是宏系列之一,它将生成所需的必要mywidget_get_type样式函数。如果你正在做一些奇怪的事情,你也可以type-func在你的 ui 文件中的对象的属性中指定函数。

但是,对于可能无法运行的简单程序(至少在 Linux 上),因为编译器可能不会将函数导出到动态符号表中,因此GtkBuilder无法找到它。所以你有几个选择。

  1. mywidget_get_type()在您的应用程序的早期调用某个地方。这将在GObject类型系统中注册类型并GtkBuilder能够找到它。我正在使用 的子类GtkApplication,所以我在我的myapp_class_init. 这感觉有点像 hack,但我选择了这个解决方案,因为它似乎应该适用于各种情况。
  2. 如果您使用的是 GCC,请将最终的可执行文件与-rdynamic. 这会将所有符号放入动态符号表中,因此上述魔法将允许GtkBuilder找到它。
  3. 在共享库中构建您的小部件。我还没有尝试过这个,但我相信它的工作原理与-rdynamic工作原理相同。
于 2015-03-31T08:23:42.630 回答