Gtkmm4拖拽DropTarget使用Bytes类型的类型断言错误求解
使用Gtkmm4实现拖拽时Glib::Bytes类型的类型验证问题
我正在尝试用Gtkmm4实现拖拽功能。在DragSource的prepare信号回调里,我返回了一个ContentProvider:
// ... char* buffer; gsize length; file->load_contents(buffer, length); auto content_bytes = Glib::Bytes::create(buffer, length); provided_content = Gdk::ContentProvider::create(columns->content_type, content_bytes); return provided_content;
DropTarget的drop信号回调定义如下:
// setup drag and drop target auto drag_target = Gtk::DropTarget::create(G_TYPE_BYTES, Gdk::DragAction::MOVE); drag_target->signal_drop().connect([this](const Glib::ValueBase& value, double x, double y) -> bool { if (G_VALUE_HOLDS(value.gobj(), Glib::Value<Glib::Bytes>::value_type())) { } }, false);
运行时出现如下错误:
In template: static assertion failed due to requirement 'std::is_default_constructible<Glib::Bytes>()': T should be default constructibleclang(static_assert_requirement_failed)
我参考了官方示例但没有用Glib::ustring,而是传递Bytes类型数据。请问有没有类似Glib::Value<Glib::Bytes>的方式,或者其他方法来验证传递的数据值类型?
解决方案
错误根源是Glib::Bytes是不可变类型,没有默认构造函数,而Glib::Value<T>模板要求T必须满足默认构造条件,因此无法直接使用Glib::Value<Glib::Bytes>。可以通过以下方式解决:
方法一:直接使用GObject的C API处理GValue
绕开Glib::Value<T>模板,直接用GValue的原生C函数来检查类型并提取数据,这是最直接的方案:
drag_target->signal_drop().connect([this](const Glib::ValueBase& value, double x, double y) -> bool { GValue* gvalue = value.gobj(); // 直接用G_TYPE_BYTES检查类型 if (G_VALUE_HOLDS(gvalue, G_TYPE_BYTES)) { // 将GValue中的boxed类型转换为Glib::Bytes智能指针 Glib::RefPtr<Glib::Bytes> bytes = Glib::wrap(g_value_get_boxed(gvalue)); // 这里可以添加对bytes的处理逻辑 return true; } return false; }, false);
方法二:自定义Glib::Value特化(不推荐)
如果一定要使用Glib::Value<T>的形式,可以为Glib::Bytes编写Glib::Value的特化模板,但需要手动实现默认构造等相关逻辑,步骤繁琐且没必要,一般推荐直接用方法一。
另外要确保DragSource中创建ContentProvider时使用的content_type和DropTarget指定的G_TYPE_BYTES完全匹配,避免类型不兼容的问题。
内容的提问来源于stack exchange,提问作者xBACP
相关产品推荐
相关产品推荐

