自定义Gtk小部件与模板UI

时间:2014-06-16 02:26:50

标签: gtk3 subclassing gtkbuilder

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

我做了什么:

  • 使用<template class="G3JAMinScenes" parent="GtkBox">
  • 写了一个.ui文件
  • 写了小部件源代码(.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'

1 个答案:

答案 0 :(得分:2)

我还没有在任何文档中找到任何正式答案。我开始挖掘GTK +源代码并找到了一些东西。

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

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

  1. 在应用程序的早期某处调用GtkBuilder。这将在mywidget_get_type()类型系统中注册类型,GObject将能够找到它。我正在使用GtkBuilder的子类,所以我在GtkApplication中调用它。这感觉有点像黑客,但我决定使用这个解决方案,因为它看起来应该适用于所有情况。
  2. 如果您使用的是GCC,请将最终的可执行文件与myapp_class_init相关联。这会将所有符号放在动态符号表中,以便上述魔法允许-rdynamic找到它。
  3. 在共享库中构建窗口小部件。我还没有尝试过这个,但我相信它应该与GtkBuilder的工作原理相同。