3

According to the GTK API reference, the "license-type" property of GtkAboutDialog is only present in GTK >= 3.0. For compatibility, my code currently checks the GTK version before setting the "license-type" property:

-- This is Lua code binding to GTK via lgi
local dialog = Gtk.AboutDialog {
    title = "About Me",
    -- ...,
}
if Gtk.check_version(3,0,0) == nil then
    dialog.license_type = Gtk.License.MIT_X11
end

Instead of doing this, is there a way to directly ask GTK if a widget supports a certain property? I think the code would be more self-documenting and less bug prone if I could write something that looks like

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

Since this question is really about the GTK API, I'm OK with answers in any programming language. Although the examples are in Lua, I assume a similar problem should show up in other dynamic-language bindings or even in C, assuming that there is a way to set properties by name without going through the set_license_type accessor function.

hugomg
  • 68,213
  • 24
  • 160
  • 246

4 Answers4

3

You can use the g_object_class_find_property() function to see if a property exists.

Note that this function takes a GObjectClass, not the GObject instance. All GObject classes come in these class-instance pairs, with the class structure used for shared things like vtable methods. To get the GObjectClass associated with an object instance, in C, you can use the G_OBJECT_GET_CLASS() macro. (If you want to do this in Lua, and if Lua can't call C macros like that, you'll have to trace the definition of G_OBJECT_GET_CLASS().)

andlabs
  • 11,290
  • 1
  • 31
  • 52
  • Thanks for your answer. Unfortunately, I never managed to find a way to call "find_property" in Lua because the Lua interface I used would wrap all the classes inside tables, and would not expose the GObjectClass pointers that "find_property" requires. The good news is that I found an alternative (Lua-only) way to solve my problem. – hugomg Jul 30 '16 at 21:08
  • Good to know. Is this solution documented in lgi anywhere? – andlabs Jul 31 '16 at 05:13
  • Dunno for sure, I kind of figured it out on my own. However, the `_property` table is a public API so I think its fine. – hugomg Jul 31 '16 at 15:37
3

You don't need to use the _property field like you are doing in your currently accepted answer since lgi finds all names in the type categories tables directly. Additionally, it is also possible to get type of an instance using _type accessor. So I'd recommend following solution:

if dialog._type.license_type then
    dialog.license_type = Gtk.License.MIT_X11
end
Community
  • 1
  • 1
1

In lgi, a class's properties are present in its _property field:

if Gtk.AboutDialog._property.license_type then
    dialog.license_type = Gtk.License.MIT_X11
end
hugomg
  • 68,213
  • 24
  • 160
  • 246
1

If for some reasons you need to know if a property is present without instantiating it, you can go with @andlabs idea in this way:

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

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

-- Does not print anything
if class:find_property('unknown') then print('yes') end
ntd
  • 7,372
  • 1
  • 27
  • 44