从 Glade 文件构建时 Gtkmm Custom Widget 抛出错误
Gtkmm Custom Widget throws error when building from Glade file
我已经制作了一个自定义小部件,并且由于缺少文档来获取扩展 Gtk::Entry
的自定义对象,因此整个下午都在苦苦挣扎。我已经到了可以在 Glade 中添加小部件的地步。我现在收到一个错误:
terminate called after throwing an instance of 'Gtk::BuilderError'
加载时。我的 gdb 技能不是很好,但我知道错误是从 auto builder = Gtk::Builder::create_from_file("glade/window_main.glade");
抛出的
这是我的自定义对象实现的样子:
...
IntEntry::IntEntry(GtkEntry *gobj) : Gtk::Entry(gobj)
{
}
IntEntry::IntEntry() : Glib::ObjectBase("intentry")
{
}
void IntEntry::set_value(int value)
{
this->value = value;
this->set_text(std::to_string(value));
}
void IntEntry::on_insert_text(const Glib::ustring &text, int *position)
{
if (is_int(text))
{
Gtk::Entry::on_insert_text(text, position);
auto full_text = this->get_text();
std::string str_text = full_text.c_str();
this->set_value(std::stoi(str_text));
}else{
Gtk::Entry::on_insert_text(text, position);
}
}
Glib::ObjectBase *
IntEntry::wrap_new(GObject *o)
{
if (gtk_widget_is_toplevel(GTK_WIDGET(o)))
{
return new IntEntry(GTK_ENTRY(o));
}
else
{
return Gtk::manage(new IntEntry(GTK_ENTRY(o)));
}
}
void IntEntry::register_type()
{
if (gtype)
return;
IntEntry dummy;
GtkWidget *widget = GTK_WIDGET(dummy.gobj());
gtype = G_OBJECT_TYPE(widget);
Glib::wrap_register(gtype, IntEntry::wrap_new);
}
extern "C" void custom_widgets_init()
{
Gtk::Main::init_gtkmm_internals();
IntEntry::register_type();
}
本文主要改编自某个网站上的博客 post,该网站已不存在,但可以找到存档 here。
我的目录是这样的:
<?xml version="1.0" encoding="UTF-8" ?>
<glade-catalog name="customwidgets" library="customwidgetsglade" depends="gtk+">
<init-function>custom_widgets_init</init-function>
<glade-widget-classes>
<glade-widget-class name="gtkmm__CustomObject_intentry" generic-name="intentry" icon-name="widget-gtk-entry" title="Int Entry">
</glade-widget-class>
</glade-widget-classes>
<glade-widget-group name="customwidgets" title="Custom Widgets" >
<glade-widget-class-ref name="gtkmm__CustomObject_intentry" />
</glade-widget-group>
</glade-catalog>
在写问题的过程中,我发现了我的问题。
我忘记在尝试使用自定义对象之前注册它们。
我需要在调用 Gtk::Builder::create_from_file("glade/window_main.glade");
之前调用 custom_widgets_init()
我已经制作了一个自定义小部件,并且由于缺少文档来获取扩展 Gtk::Entry
的自定义对象,因此整个下午都在苦苦挣扎。我已经到了可以在 Glade 中添加小部件的地步。我现在收到一个错误:
terminate called after throwing an instance of 'Gtk::BuilderError'
加载时。我的 gdb 技能不是很好,但我知道错误是从 auto builder = Gtk::Builder::create_from_file("glade/window_main.glade");
这是我的自定义对象实现的样子:
...
IntEntry::IntEntry(GtkEntry *gobj) : Gtk::Entry(gobj)
{
}
IntEntry::IntEntry() : Glib::ObjectBase("intentry")
{
}
void IntEntry::set_value(int value)
{
this->value = value;
this->set_text(std::to_string(value));
}
void IntEntry::on_insert_text(const Glib::ustring &text, int *position)
{
if (is_int(text))
{
Gtk::Entry::on_insert_text(text, position);
auto full_text = this->get_text();
std::string str_text = full_text.c_str();
this->set_value(std::stoi(str_text));
}else{
Gtk::Entry::on_insert_text(text, position);
}
}
Glib::ObjectBase *
IntEntry::wrap_new(GObject *o)
{
if (gtk_widget_is_toplevel(GTK_WIDGET(o)))
{
return new IntEntry(GTK_ENTRY(o));
}
else
{
return Gtk::manage(new IntEntry(GTK_ENTRY(o)));
}
}
void IntEntry::register_type()
{
if (gtype)
return;
IntEntry dummy;
GtkWidget *widget = GTK_WIDGET(dummy.gobj());
gtype = G_OBJECT_TYPE(widget);
Glib::wrap_register(gtype, IntEntry::wrap_new);
}
extern "C" void custom_widgets_init()
{
Gtk::Main::init_gtkmm_internals();
IntEntry::register_type();
}
本文主要改编自某个网站上的博客 post,该网站已不存在,但可以找到存档 here。
我的目录是这样的:
<?xml version="1.0" encoding="UTF-8" ?>
<glade-catalog name="customwidgets" library="customwidgetsglade" depends="gtk+">
<init-function>custom_widgets_init</init-function>
<glade-widget-classes>
<glade-widget-class name="gtkmm__CustomObject_intentry" generic-name="intentry" icon-name="widget-gtk-entry" title="Int Entry">
</glade-widget-class>
</glade-widget-classes>
<glade-widget-group name="customwidgets" title="Custom Widgets" >
<glade-widget-class-ref name="gtkmm__CustomObject_intentry" />
</glade-widget-group>
</glade-catalog>
在写问题的过程中,我发现了我的问题。
我忘记在尝试使用自定义对象之前注册它们。
我需要在调用 Gtk::Builder::create_from_file("glade/window_main.glade");
custom_widgets_init()