Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to change data from a QModelIndex



  • Hi all,

    I have a QTableView displaying a QAbstractTableModel.
    I am trying to amend the content of a cell when double clicking on it (from False to True)
    I managed to retrieve the double click signal and to display the data, the row and the column of the cell double clicked. What I do not manage to do is to amend this data. Could you please help ? Thx

    class MyTableView(QTableView):
    def __init__(self, *args):
        QTableView.__init__(self, *args)
        self.doubleClicked.connect(self.slotDoubleClicked)
    
    def slotDoubleClicked(self, index):
        if index.isValid():
            print(index.data(Qt.DisplayRole))
            print(index.row)
            print(index.column)
    
    # Table model
    class TicketGUI(QAbstractTableModel):
        def __init__(self):
        QAbstractTableModel.__init__(self)
         self.tickets = Tests()
         data = self.tickets.toDataframe()
         self._data = data
    

  • Lifetime Qt Champion

    Hi
    Im not 100% sure what you ask, but
    You can use the models
    https://doc.qt.io/qt-5/qabstractitemmodel.html#setData
    to change the data and you might need to call dataChanged(...) too to inform the view
    that data changed.



  • @mrjj Thanks. I tried to do the following within my slotDoubleClicked function but it crash without any error message:

    index.model.setData(1, Qt.EditRole)
    


  • @alaintk
    I think you'll find model is a function, IIRC. So:

    index.model().setData(1, Qt.EditRole)
    

    Lovely Python will happily let you write model... and then crash, unlike C++....



  • @jonb thanks, here I am now: I am able to amend the cell in my view but it is not affecting the content of my object, how can I amend my object and not the display

    class MyTableView(QTableView):
    def __init__(self, *args):
        QTableView.__init__(self, *args)
        self.doubleClicked.connect(self.slotDoubleClicked)
    
    def slotDoubleClicked(self, index):
        if index.isValid():
                if index.data(Qt.DisplayRole) == False:
                    self.model().setData(index, QVariant(""), Qt.EditRole)
    
    class TicketGUI(QAbstractTableModel):
        def __init__(self):
        QAbstractTableModel.__init__(self)
         self.tickets = Tests()
         data = self.tickets.toDataframe()
         self._data = data 
    
    def setData(self, index, value, role=Qt.EditRole):
            if index.isValid():
                self._data.iloc[index.row(), index.column()] = True
                return True
            return False
    

  • Lifetime Qt Champion

    Hi,

    You are not emitting the dataChanged signal when modifying your model content, therefore your view is not informed to update itself.



  • @sgaist No my view is updating but not the content of my object...


  • Lifetime Qt Champion

    @alaintk
    hi
    What is "my object" ?
    There is the view and the model.
    And you say the view will update when you change the model so
    that is working it seems.

    So what is not updating, that is not the view nor the model ???



  • @alaintk
    First, what @SGaist has said is correct, you ought to have to emit dataChanged from your setData() but you're not. That ought to make the view not update, though we have to respect that you are saying it does.

    Then I have to assume your

    if index.data(Qt.DisplayRole) == False
    

    is being hit (you've verified that, right?).

    Don't really know precisely what you mean by "my object", and how you know it is "not being updated".

    One thing puzzles me: you seem to have overridden setData() to alter self._data.iloc[index.row(), index.column()]. But I do not see a corresponding override of data() method to return that? If not, you are setting one thing but not getting the same thing..??

    Finally, you are deriving from QAbstractTableModel but I don't see all the overrides you should need for that? See e.g. https://stackoverflow.com/questions/14189693/how-to-set-data-inside-a-qabstracttablemodel, or possibly https://stackoverflow.com/questions/5869531/how-do-i-keep-my-qabstracttablemodel-in-sync-with-my-data-store may be relevant to your situation.



  • @alaintk
    OK, I'm thinking this is to do with your

    data = self.tickets.toDataframe()
    

    You have a Pandas dataframe or something, I imagine? (Might have helped if you had explained...) Then I would guess you must copy changes back to that? The model, I think, is effectively working on a copy of your "dataframe", not the original object? Have a read of https://stackoverflow.com/questions/44603119/how-to-display-a-pandas-data-frame-with-pyqt5


Log in to reply