How to get selected elements of TGListView

Hello,

I am trying to get the currently selected TGLVEntry from TGListView. From the main ROOT group I got, that I should use

TGContainer::GetNextSelected(void** current)

for that purpose. Well, here comes a pyROOT question - how to declare void**?

Hi,

I’m not familiar with this function, so I don’t know what the eventual goal is. I’ll assume in the following that you are getting an array of pointers to objects back from the call.

In that case, you can use:import array vp = array.array('L', [0]*desired_size)
Pass that, and then to cast return values to the objects, use ROOT.BindObject(vp[index], “desired_class”) for each of the objects.

Cheers,
Wim

My goal is to retrieve the selected TGLVElement of the list…

Hi,

not sure how that is supposed to be used (I see now code example). But reading the implementation, it seems that the input can be zero, and only needs to be 1 long. So yes, an array(‘L’, [0]) with a cast of the return value should do the trick, with subsequent calls (with the same array as argument) iterating through the elements.

Cheers,
Wim

It works, thanks!

However, now a bug report or a feature request. It seems, that two different TGLVEntry items are the same for pyROOT when using “==” operator. For example output of:

print item, self.prev_selection, item==self.prev_selection

can be:

<ROOT.TGLVEntry object ("fLVEntry63") at 0x7f9dfc0a3b60> <ROOT.TGLVEntry object ("fLVEntry57") at 0x7f9dfc0a2de0> True

so direct comparison of the list items cannot be done. It can be done of course using the name and subnames, but it would be more convenient to directly compare objects.

Hi,

that is very odd … unless overridden (which I can’t find for this class), the comparison should be on pointers. You can always use the base class comparison (which is based on pointer + type):from ROOT import ObjectProxy ObjectProxy.__eq__(item, self.prev_selection)I’ll do some digging to see where the true is coming from…

Cheers,
Wim

Hi,

found it … TObject::IsEqual is pythonized in that that function is a stand-in for operator==. This is fine, as it does a direct pointer comparison by default (and TObject hierarchies are flat, as a rule), and does what a derived class wants it to do when overridden.

Problem is that TGObject, from which TGLVEntry derives, overrides that function with: Bool_t IsEqual(const TObject *obj) const { return fId == ((const TGObject *) obj)->fId; }and as it happens, TGLVEntry’s seem to have fId’s of 0L (presumably never set/used). Otherwise, fId is an opaque window handle.

So, can’t really be helped from python, as it just follows what it is instructed to do from the C++ code. You can, however, make a global change to all TGLVEntry objects:from ROOT import TGLVEntry, ObjectProxy TGLVEntry.__eq__ = ObjectProxy.__eq__ TGLVEntry.__ne__ = ObjectProxy.__ne__which will then to type/pointer comparisons.

Cheers,
Wim

Thanks! I’ll make use of it.

However, it seems like a bug in TGLVEntry - perhaps something should be done with the Id or the == operator reimplemented… Should I send it to the main list?

Hi,

yes, if you want that behavior changed, it should be send upstream. It’s definitely beyond my remit.

Cheers,
Wim