how to implement a custom QAbstractItemModel for PathListingWidget

370 views
Skip to first unread message

Hradec

unread,
Feb 26, 2017, 11:44:26 PM2/26/17
to gaffer-dev

Hradec
I'm trying to set a new QAbstractItemModel for PathListingWidget, without much success.

Although PathListingWidget has a setModel method, It doesn't seem to accept a standard QAbstractItemModel.

I tried to dig a bit and found the PathModel class, which seems to be the proper QAbstractItemModel implementantion that PathListingWidget needs, but it seems it's not bind to python.

The reason I'm trying to override QAbstractItemModel is just to be able to implement a custom data() method so I can change the background color on a per item basis. (Like to show an item is updated (green) or needs to be updated (red))

Any ideas on how I can override PathModel to implement my own data method? 
Or maybe some other idea on how to set a different background color for each individual item?


garvit verma

unread,
Feb 27, 2017, 12:22:57 AM2/27/17
to gaffer-dev
Hey Roberto,

I have done a very similar thing by implementing the model similar to GafferUIBindings/PathListingWidgetBinding.CPP that's where the model of the current PathListingWidget is kept but the _pathListingWidgetUpdateModel method only takes in a Gaffer.Path object which is then internally converted into the model that you see as the UI.

PathModel class is in C++ though, and I converted to a Python class,although the model i made is specific to the needs of our pipeline, but can definitely be rewritten to suit your needs.

You can also probably look at GafferUI/VectorDataWidget.py , becuase it has a custom QAbstractTableModel.

I hope this was some help.

Cheers
Garvit.

john haddon

unread,
Feb 28, 2017, 8:09:26 AM2/28/17
to gaffer-dev
Hi guys,

Please bear in mind that the GafferUI API intentionally hides its Qt internals to present a Qt-free public API. So although you may be able to achieve what you want by monkey patching behind the scenes, that is not something we can provide any support for.

The public PathListingWidget API allows the internal model to be manipulated indirectly using the `setColumns()` method and the equivalent `columns` argument to the constructor. As Garvit says, the different column types that are available are implemented in GafferUIBindings/PathListingWidgetBinding.cpp., so the right way to add support for coloured backgrounds would be to add colour support to the StandardColumn. This is something I expect we'll get to doing eventually to support a better experience in the SceneHierarchy panel, but if you fancy taking a look at contributing it yourself, that would be great.

Do you already have a colour property on your Path class Hradec? Or will you be wanting to map a non-colour property into a background colour using some sort of rule?

Cheers...
John

Hradec

unread,
Feb 28, 2017, 5:13:26 PM2/28/17
to gaffer-dev
Please bear in mind that the GafferUI API intentionally hides its Qt internals to present a Qt-free public API. So although you may be able to achieve what you want by monkey patching behind the scenes, that is not something we can provide any support for.

Totally understand!!
 

The public PathListingWidget API allows the internal model to be manipulated indirectly using the `setColumns()` method and the equivalent `columns` argument to the constructor. As Garvit says, the different column types that are available are implemented in GafferUIBindings/PathListingWidgetBinding.cpp., so the right way to add support for coloured backgrounds would be to add colour support to the StandardColumn. This is something I expect we'll get to doing eventually to support a better experience in the SceneHierarchy panel, but if you fancy taking a look at contributing it yourself, that would be great.
 
I see... I had a look at the code and notice the Item.data() method actually calls the column.data() method indeed!

In my original question I was asking specifically about backgroung color, but when one think about it, it would be ideal to be able to decorate the item not only with background color, but with anything that a  Qt.DecorationRole allow, like font, icons, background/foreground colors, etc. 

What about add a mechanism to setup a python coded data() function to be called by  StandardColumn::data(), if it exists?

That way one can easily intercept role calls and customize the return as needed. 

Unfortunately, I don't known much about boost.python to do it by myself at this point. 

Do you already have a colour property on your Path class Hradec? Or will you be wanting to map a non-colour property into a background colour using some sort of rule?

RULES. I need something like this:

Inline image 3

So, the faint background colors are to separate and identify the types of assets (animation/camera/model/render in this case).
And the red lights, when running in maya or any other app, they need to turn green when an asset is up2date, yellow when is outdated, for example. 

Our asset types are implemented as op classes, with some extra methods to interface with different applications.  (for example, all asset types have a doMayImport method which is called when maya checkouts the asset)

In the same fashion, the decoration would be provided by a method in the asset type code. 

This mocap screenshot was done in standard PyQt4, with a standard QTreeView. 

Because I need to have this working asap, I'll probably turn it into a python GafferUI.Widget for now, to be used in place of PathListingWidget.

cheers...
-H


garvit verma

unread,
Mar 1, 2017, 3:12:45 AM3/1/17
to gaffer-dev
I understand the fact that the API provides abstraction from core Qt calls.

I actually ended up creating an IconColumn, and a custom path class to get the widget running, as per my requirements.

My aim for implementing the Python class similar to the one in C++, was just for learning how the parent-child are getting created in treeview.

Also, I wanted to determine, if it would need a change in the way model is populating data for the view to integrate the changes I was trying to make, I didn't mean to monkey patch and use the Python class instead. Python class was simply for prototyping.

I would love to contribute back to gaffer, as that would help me learn more about it myself.

John Haddon

unread,
Mar 1, 2017, 4:07:38 AM3/1/17
to gaffe...@googlegroups.com
What about add a mechanism to setup a python coded data() function to be called by  StandardColumn::data(), if it exists?

The problem is that would be exposing Qt publicly, because `data()` takes and returns Qt types. I think an approach we're more likely to take is one where we add methods like `virtual Imath::Color4f Column::backgroundColor( const Path * )`, so you can do what you want without us exposing Qt. How does that sound?
 
This mocap screenshot was done in standard PyQt4, with a standard QTreeView. 

It looks good - can definitely see why the additional features are needed in PathListingWidget. 

Because I need to have this working asap, I'll probably turn it into a python GafferUI.Widget for now, to be used in place of PathListingWidget.

I think that's a reasonable approach. Presumably you've figured out that you can always construct a GafferUI.Widget passing a QWidget to be wrapped? This is a much better approach than trying to fiddle with the internals of something like PathListingWidget. It would stop working if we moved away from Qt obviously, but that's unlikely, whereas the likelihood of us changing the internals of any given class is high...

Cheers...
John 

Hradec

unread,
Mar 2, 2017, 1:51:02 PM3/2/17
to gaffer-dev
The problem is that would be exposing Qt publicly, because `data()` takes and returns Qt types. I think an approach we're more likely to take is one where we add methods like `virtual Imath::Color4f Column::backgroundColor( const Path * )`, so you can do what you want without us exposing Qt. How does that sound?

Off course... you're totally right, as usual!! For sure that makes perfect sense!
 
I think that's a reasonable approach. Presumably you've figured out that you can always construct a GafferUI.Widget passing a QWidget to be wrapped? This is a much better approach than trying to fiddle with the internals of something like PathListingWidget. It would stop working if we moved away from Qt obviously, but that's unlikely, whereas the likelihood of us changing the internals of any given class is high...

Yeah... implementing a new GafferUI.Widget is really simple indeed, and works perfectly! 

I'm actually loving Gaffer so far!! Awesome work guys!!

cheers...
-H
 

Reply all
Reply to author
Forward
0 new messages