Maya signal tp update data with QAbstractItemModel?

Hi all,

I am creating a UI in PySide and i use QAbstractItemModel.
This UI show renderLayers from a Maya scene.

r1 = RenderLayersClass("renderLayer01", "cam01", "1-10")
r2 = RenderLayersClass("renderLayer01", "cam02", "5-10")
r3 = RenderLayersClass("renderLayer02", "cam01", "1-10")
r4 = RenderLayersClass("renderLayer0fjfjf", "cam01", "1-10")

DeadlineSubmitter([r1, r2, r3, r4])

After i have this :

class DeadlineSubmitter(QtGui.QWidget):
    '''
    classdocs
    '''

    def __init__(self, renderLayers, parent=None):
        '''
        Constructor
        '''
        QtGui.QWidget.__init__(self, None)
        self.ui = deadlineSubmitterUI.Ui_deadlineSubmitter_main()
        self.ui.setupUi(self)

        self._proxyModel = QtGui.QSortFilterProxyModel(self)
        self._model = SceneListModel(renderLayers)

SceneListModel is a QAbstractItemModel.
All is working perfectly.
When i change my data on my UI, all data are updated.

But now i have 2 problems :

  1. If the user add a new renderLayer in Maya, obviously, i have to create a new RenderLayersClass().
    But, how can i know that there is a new renderLayer ? Scriptjob (no no…) ? Enter event in my DeadlineSubmitter ?

  2. RenderLayersClass have some attributes like : RenderLayersClass.camera
    I change the data of my RenderLayersClass manually (not by the view) like : RenderLayersClass.camera = ‘perpShape’
    How can i update the UI ?
    I know that i have to use self._model.setData(), because i emit “dataChange()” in this function. But setData(index, value, role=QtCore.Qt.EditRole), as you can see, need an index and value.

Thank you.

Ok, here a better example. I have this :

from PySide import QtGui, QtCore

class ListMOdel(QtCore.QAbstractListModel):
    def __init__(self , data=[] ,parent=None):
        QtCore.QAbstractListModel.__init__(self,parent)
        self.__data=data

    def rowCount(self ,parent):
        return len(self.__data)

    def data(self,index,role):

        if role == QtCore.Qt.DisplayRole:
            row=index.row()
            value = self.__data[row]
            return value

    def flags(self,index):
        return QtCore.Qt.ItemIsEditable |QtCore.Qt.ItemIsEnabled| QtCore.Qt.ItemIsSelectable

    def setData(self,index,value,role=QtCore.Qt.EditRole):
        if role == QtCore.Qt.EditRole:
            row= index.row()
            self.__data[row]=value
            return True
        return False

class MainWin52(QtGui.QMainWindow):
    itemName = ""
    def __init__(self, inheritance=None):
        super(MainWin52, self).__init__()
        self.listView= QtGui.QListView(self)  

        self.wordList = []
        self.model = None
        self.showListView()
        self.itemName = ""


    def showListView(self):
        self.wordList = ['totot', 'pooppo', 'ddddd']
        data=[]
        for row in self.wordList:
            data.append(row)

        self.model = ListMOdel(data, self)
        self.listView.setModel(self.model)
        
a = MainWin52()
a.show()

Now i do this :

a.wordList = ['hello1','hello2']

Nothing happen, the view is not refreshed.
How can i update the UI when data change ?

simplest way would be to define a wordlist setter that updates the model.


    @property
    def wordlist(self):
        return self.wordlist

    @wordlist.setter
    def wordlist(self, words):
        self.wordlist = words
        self.refreshUI()

    def refreshUI(self):
        self.model = ListModel(self.wordlist, self)
        self.listView.setModel(self.model)

So to refresh the UI, you use :


self.model = ListModel(self.wordlist, self)
self.listView.setModel(self.model)

But with this method, i lost all my selection, this is like a self.model.reset()

With the example you gave, you are replacing the word list. ([‘totot’, ‘pooppo’, ‘ddddd’] is replaced with [‘hello1’,‘hello2’].) If you want to keep your selection, then I am assuming you actually want to append to the word list?

If this is the case, you could make your own function in the ListModelClass to add items to your model. It is important to call beginInsertRows() before adding the new data, and call endInsertRows() when you are done. Something along the lines of:


def appendItems(self, itemList):
    rowCount = self.rowCount()
    self.beginInsertRows(QtCore.QModelIndex(), rowCount, rowCount+len(itemList)-1)
    self.__data.extend(itemList)
    self.endInsertRows()

Then you could do something like:

a.model.appendItems(['hello1', 'hello2'])

(This code is not tested. Please forgive any errors.)