Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to make QAbstractTableModel 's data checkable
Forum Updated to NodeBB v4.3 + New Features

How to make QAbstractTableModel 's data checkable

Scheduled Pinned Locked Moved Qt for Python
6 Posts 3 Posters 9.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    redstoneleo
    wrote on last edited by
    #1

    I want to make each cell in the following code can be checked or unchecked by the user ,how to modify the code ?

    @import sys

    from PyQt4.QtGui import *

    from PyQt4.QtCore import *

    class MyModel(QAbstractTableModel):

    def __init__(self, parent=None):   
                          
        super(MyModel, self).__init__(parent)   
                          
    def rowCount(self, parent = QModelIndex()):   
                          
        return 2
                          
                                  
                          
    def columnCount(self,parent = QModelIndex()) :   
                          
        return 3
                          
                              
                          
    def data(self,index, role = Qt.DisplayRole) :   
                          
        if (role == Qt.DisplayRole):   
                          
            return "Row{}, Column{}".format(index.row() + 1, index.column() +1)   
                          
        return None
    

    if name == 'main':

    app =QApplication(sys.argv)   
                          
    tableView=QTableView()   
                          
    myModel = MyModel (None);   
                          
    tableView.setModel( myModel );   
                          
    tableView.show();   
    sys.exit(app.exec_())@
    
    1 Reply Last reply
    0
    • jazzycamelJ Offline
      jazzycamelJ Offline
      jazzycamel
      wrote on last edited by jazzycamel
      #2

      To be checkable, a model must return the necessary flag from the flags() method, provide legal data from the data() method with the CheckStateRole and also implement the setData() method to allow for the check state to change. See the following full example:

      import sip
      sip.setapi('QString',2)
      sip.setapi('QVariant',2)
      
      from PyQt4.QtGui import *
      from PyQt4.QtCore import *
                               
      class MyModel(QAbstractTableModel):
          def __init__(self, parent=None):
              QAbstractTableModel.__init__(self, parent)
      
              self._checked=[[False for i in xrange(self.columnCount())] for j in xrange(self.rowCount())]
                               
          def rowCount(self, parent = QModelIndex()): return 2
          def columnCount(self,parent = QModelIndex()): return 3
      
          def data(self,index, role = Qt.DisplayRole):
              if not index.isValid(): return
              if (role == Qt.DisplayRole):
                  return "Row{}, Column{}".format(index.row()+1, index.column()+1)
              elif role==Qt.CheckStateRole: return self._checked[index.row()][index.column()]
              return None
      
          def flags(self, index):
              if not index.isValid(): return
              return Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsUserCheckable
      
          def setData(self, index, value, role):
              if not index.isValid() or role!=Qt.CheckStateRole: return False
              self._checked[index.row()][index.column()]=value
              self.dataChanged.emit(index, index)
              return True
      
      if __name__ == '__main__':
          from sys import argv, exit
      
          class Widget(QWidget):
              def __init__(self, parent=None, **kwargs):
                  QWidget.__init__(self, parent, **kwargs)
      
                  l=QVBoxLayout(self)
                  self._model=MyModel(self)
                  self._table=QTableView(self)
                  self._table.setModel(self._model)
                  l.addWidget(self._table)
      
          app=QApplication(argv)                         
          w=Widget()
          w.show()
          w.raise_()
          exit(app.exec_())
      

      Hope this helps ;o)

      For the avoidance of doubt:

      1. All my code samples (C++ or Python) are tested before posting
      2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
      1 Reply Last reply
      1
      • R Offline
        R Offline
        redstoneleo
        wrote on last edited by
        #3

        is it necessary to check if the index is valid ?
        I post a thread about this question here ,can you have a look ?
        http://qt-project.org/forums/viewthread/26955/

        1 Reply Last reply
        0
        • jazzycamelJ Offline
          jazzycamelJ Offline
          jazzycamel
          wrote on last edited by
          #4

          I am in the habit of always checking the validity of the index when working with models of any shape (list, table, tree) or dimension. With tree models it's more important, but even with lists and tables, for what it realistically costs (which is very little), a bit of defensive programming to prevent unseemly UI errors, crashes or even segmentation faults (this can happen!) is worth it. I regularly work with models that are 100's and 1000's of columns wide and 1,000,000's of rows long and it doesn't have an adverse effect.

          WRT to this:

          @
          if (!index.isValid())
          return QVariant();

           if (index.row() >= stringList.size())
               return QVariant();
          

          @

          The second check is entirely contextual: if/how you do this is based on the likelihood of bad/non-existant accesses and the underlying data structures ability to handle these.

          So I suppose the long and the short of it is: check the validity of the index as there's no reason not to, check the validity of the data access as/if/when appropriate to your design.

          Hope this answers your question ;o)

          For the avoidance of doubt:

          1. All my code samples (C++ or Python) are tested before posting
          2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
          1 Reply Last reply
          1
          • R Offline
            R Offline
            redstoneleo
            wrote on last edited by
            #5

            a minimized example

            import sys
            
            from PySide2.QtWidgets import *
            from PySide2.QtCore import *
            from PySide2.QtGui import *
            from PySide2.QtSql import *
            
            
            class MyModel(QSqlTableModel):
                def __init__(self, parent=None):
                    super().__init__(parent)
                    self._checked = [[False for i in range(self.columnCount())] for j in range(self.rowCount())]
            
                def rowCount(self, parent=QModelIndex()):
                    return 2
            
                def columnCount(self, parent=QModelIndex()):
                    return 3
            
                def data(self, index, role):
                    if (role == Qt.DisplayRole):
                        return "Row{}, Column{}".format(index.row() + 1, index.column() + 1)
                    elif role == Qt.CheckStateRole:
                        print('data(self, index, role)-------------', index.data())
                        return self._checked[index.row()][index.column()]  # show CheckBox's check state
                    return None  # be sure to return super().data(index, role) if worked with QSqlTableModel;
            
                def flags(self, index):
                    return super().flags(index) | Qt.ItemIsUserCheckable
            
                def setData(self, index, value, role):  # implement the setData() method to allow for the check state to change
                    if role == Qt.CheckStateRole:
                        print(value)
                        self._checked[index.row()][index.column()] = value  # CheckBox's check state depends on the value
                        return True  # Returns true if the value could be set
                    return False  # be sure to return super().setData(index, value, role) if worked with QSqlTableModel;Returns true if value is equal to the current value. However, the value will not be submitted to the database.;
            
            
            if __name__ == '__main__':
                app = QApplication(sys.argv)
                tableView = QTableView()
                myModel = MyModel(None)
                tableView.setModel(myModel)
                tableView.show()
                sys.exit(app.exec_())
            
            
            R 1 Reply Last reply
            2
            • R redstoneleo

              a minimized example

              import sys
              
              from PySide2.QtWidgets import *
              from PySide2.QtCore import *
              from PySide2.QtGui import *
              from PySide2.QtSql import *
              
              
              class MyModel(QSqlTableModel):
                  def __init__(self, parent=None):
                      super().__init__(parent)
                      self._checked = [[False for i in range(self.columnCount())] for j in range(self.rowCount())]
              
                  def rowCount(self, parent=QModelIndex()):
                      return 2
              
                  def columnCount(self, parent=QModelIndex()):
                      return 3
              
                  def data(self, index, role):
                      if (role == Qt.DisplayRole):
                          return "Row{}, Column{}".format(index.row() + 1, index.column() + 1)
                      elif role == Qt.CheckStateRole:
                          print('data(self, index, role)-------------', index.data())
                          return self._checked[index.row()][index.column()]  # show CheckBox's check state
                      return None  # be sure to return super().data(index, role) if worked with QSqlTableModel;
              
                  def flags(self, index):
                      return super().flags(index) | Qt.ItemIsUserCheckable
              
                  def setData(self, index, value, role):  # implement the setData() method to allow for the check state to change
                      if role == Qt.CheckStateRole:
                          print(value)
                          self._checked[index.row()][index.column()] = value  # CheckBox's check state depends on the value
                          return True  # Returns true if the value could be set
                      return False  # be sure to return super().setData(index, value, role) if worked with QSqlTableModel;Returns true if value is equal to the current value. However, the value will not be submitted to the database.;
              
              
              if __name__ == '__main__':
                  app = QApplication(sys.argv)
                  tableView = QTableView()
                  myModel = MyModel(None)
                  tableView.setModel(myModel)
                  tableView.show()
                  sys.exit(app.exec_())
              
              
              R Offline
              R Offline
              Rodrigo B.
              wrote on last edited by
              #6

              @redstoneleo Thanks, it's incredible how hard it is to find a straightforward example of this functionality.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved