如何判断一个 GTK 小部件是否支持某个属性而无需检查版本号?

根据 GTK API 参考文档,GtkAboutDialog 的 "license-type" 属性仅在GTK >= 3.0中存在。出于兼容性,我的代码当前在设置 "license-type" 属性之前检查GTK版本:

-- 这是通过lgi绑定到GTK的Lua代码
local dialog = Gtk.AboutDialog {
    title = "About Me",
    -- ...,
}
if Gtk.check_version(3,0,0) == nil then
    dialog.license_type = Gtk.License.MIT_X11
end

除了这样做,是否有一种方法可以直接询问 GTK 是否支持某个小部件属性? 如果我可以编写类似于以下内容的代码,那么代码将更容易自我记录,并且具有更少的错误倾向:

if supports_property(dialog, "license-type") then
    dialog.license_type = Gtk.License.MIT_X11
end

因为这个问题实际上是关于GTK API的,所以我可以接受任何编程语言的答案。虽然示例是用Lua编写的,但我假设类似问题应该出现在其他动态语言绑定中,甚至在使用名称设置属性而无需通过 set_license_type 访问器函数的C中也可能会出现。

点赞
用户3408572
用户3408572

你可以使用g_object_class_find_property()函数查看属性是否存在。

需要注意的是,此函数使用的是GObjectClass而不是GObject实例。所有的GObject类都有类实例对应,类结构用于共享的属性,如vtable方法。在C语言中,要获取与对象实例关联的GObjectClass,可以使用G_OBJECT_GET_CLASS() 宏。(如果你想在Lua中实现,但是Lua无法调用这样的C宏,那么你将需要追踪G_OBJECT_GET_CLASS()的定义。)

2016-07-28 17:58:47
用户90511
用户90511

在 lgi 中,一个类的属性位于其 _property 字段中:

if Gtk.AboutDialog._property.license_type then
    dialog.license_type = Gtk.License.MIT_X11
end
2016-07-28 22:00:18
用户7194503
用户7194503

你不需要像你 目前已接受的答案 中所做的那样使用 _property 字段,因为 lgi 直接在类型类别表中查找所有名称。 此外,还可以使用 _type 访问器获取实例的类型。因此,我建议采用以下解决方案:

if dialog._type.license_type then
    dialog.license_type = Gtk.License.MIT_X11
end
2016-11-22 12:38:13
用户186347
用户186347

如果由于某些原因你需要知道一个属性是否存在但需要实例化它,你可以按照@andlabs的想法这样做:

local lgi   = require'lgi'
local Gtk   = lgi.require'Gtk'
local class = Gtk.AboutDialogClass()

-- 打印 yes
if class:find_property('license') then print('yes') end

-- 不打印任何信息
if class:find_property('unknown') then print('yes') end
2018-04-30 07:39:17