使用gi-gtk创建Gtk3窗口时触发严重错误的排查求助
问题描述
使用Haskell的gi-gtk(3.0.39)模块将程序移植到GTK3(3.24.28)时,启动程序出现以下严重错误:
(process:13364): Gtk-CRITICAL **: 09:07:59.826: _gtk_css_lookup_resolve: assertion '(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((provider)); GType __t = ((_gtk_style_provider_private_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))' failed (process:13364): GLib-GObject-CRITICAL **: 09:07:59.826: g_object_set_data_full: assertion 'G_IS_OBJECT (object)' failed (process:13364): Gtk-ERROR **: 09:07:59.826: Can't create a GtkStyleContext without a display connection Trace/breakpoint trap
其中_gtk_css_lookup_resolve看起来和CSS相关。为定位问题编写了极简测试程序,运行后同样失败:
module Main where import GI.Gtk.Objects.Widget import GI.Gtk.Objects.Window import GI.Gtk.Enums main= do putStrLn "a" window <- windowNew WindowTypeToplevel -- (AnotherWindowType 1) putStrLn "b" widgetShowAll window
程序仅输出"a",未输出"b",说明windowNew调用失败,尝试所有WindowType均无法解决。请问该程序问题何在?如何修复?此问题是否与GTK用CSS设置样式有关?
问题分析与修复
问题根源
GTK程序启动的核心要求是必须先完成GTK库的初始化,建立与显示系统的连接。测试代码直接调用windowNew创建窗口,跳过了初始化步骤,导致GTK无法获取显示连接,进而无法创建窗口所需的样式上下文(StyleContext),触发了报错信息中的连锁错误。
修复方法
在main函数开头调用GTK的初始化函数init(来自GI.Gtk模块),完成库的初始化和显示连接建立。修改后的完整代码如下:
module Main where import GI.Gtk (init, main) import GI.Gtk.Objects.Widget import GI.Gtk.Objects.Window import GI.Gtk.Enums main= do putStrLn "a" _ <- init Nothing -- 初始化GTK,建立显示连接 window <- windowNew WindowTypeToplevel putStrLn "b" widgetShowAll window main -- 启动GTK主事件循环
说明:
init Nothing:使用默认参数初始化GTK,Nothing表示让GTK自动处理命令行参数(不需要处理参数时也可传此值)main函数:启动GTK的主事件循环,否则窗口会一闪而过立即退出
关于CSS相关错误的说明
报错中的_gtk_css_lookup_resolve错误是派生错误,并非CSS设置本身有问题。根源是缺少显示连接,GTK无法创建样式上下文对象,进而导致CSS查找逻辑失败。完成GTK初始化后,该错误会自动消失。
内容的提问来源于stack exchange,提问作者JeanJouX
相关产品推荐
相关产品推荐

