Haskell GTK绑定中如何从ByteString创建Pixbuf?
Haskell GTK程序窗口图标设置问题解答
原始代码与问题场景
以下是一段基于Haskell GTK绑定的GUI代码,意图通过file-embed库在编译时将图片嵌入为ByteString,再转换为Pixbuf类型,为主窗口设置图标:
let myFile = $(embedFile "img/termonad-lambda.png") let wordsss = unpack myFile img_ptr <- mallocBytes (length wordsss) forM_ (zip wordsss [0 ..]) $ \(word8, off) -> pokeByteOff img_ptr off (CUChar word8) pb <- pixbufNewFromData img_ptr ColorspaceRgb False 8 50 50 (50 * 3) GI.Gtk.Objects.Window.windowSetDefaultIcon pb
运行代码后,最后一行触发如下编译错误:
• Could not deduce: Data.GI.Base.Overloading.CheckForAncestorType Pixbuf gi-gdkpixbuf-2.0.29:GI.GdkPixbuf.Objects.Pixbuf.Pixbuf (Data.GI.Base.Overloading.ParentTypes Pixbuf) arising from a use of ‘windowSetDefaultIcon’
问题解答
错误含义通俗解释
这个错误本质是类型不匹配:你传给windowSetDefaultIcon的pb,和函数期望接收的Pixbuf类型不是同一回事。具体来说,GI绑定的类型系统无法确认你的pb是函数要求的那个Pixbuf类型(可能是导入别名、类型命名冲突,或者转换过程中生成的类型不符合要求),编译器没法自动推导两者的兼容性,所以报错。ByteString转Pixbuf的正确方法
手动分配内存并逐个字节写入的方式容易出问题,推荐使用bytesNewTake配合pixbufNewFromBytes的方式,更符合GI绑定的内存管理逻辑。
最终可用代码
在他人帮助下,修正后的可用代码如下:
let myFile = $(embedFile "img/termonad-lambda.png") let wordsss = unpack myFile img_ptr <- newArray (map CUChar wordsss) ccc <- GI.GLib.Structs.Bytes.bytesNewTake (Just myFile) pb <- pixbufNewFromBytes ccc ColorspaceRgb False 8 50 50 (50 * 3) GI.Gtk.Objects.Window.windowSetIcon win (Just pb)
内容的提问来源于stack exchange,提问作者Refael Sheinker
相关产品推荐
相关产品推荐

