Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-1308

QAbstractItemModel & QTableView with more than one QStyledItemDelegateForColumn, crashes my app

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • Not Evaluated
    • None
    • 5.14.2.1
    • PySide
    • None
    • Windows
    • This is not clearly Qt bug

    Description

       
      This may not be only in PySide2 but I can use only Qt for Python.

      You can see two subclasses of QStyledItemDelegate.

      IconDelegate & Delegate.

      I set these delegates into the TableModel by setItemDelegateForColumn.

      If I set both of them at one time, my app crashes.

      On the other hand, if I detach one of them , my app goes well. 

      Crash happens when I push 1 key, or try to expand the gui to right direction.

       Crash happens when I push 1 key, or try to expand the gui to Right.

      from PySide2 import QtWidgets
      from PySide2 import QtCore
      from PySide2 import QtGui
      import os
      import PySide2
      import sys
      dirname = os.path.dirname(PySide2.__file__)
      plugin_path = os.path.join(dirname, 'plugins', 'platforms')
      os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
      alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"]
      class IconDelegate(QtWidgets.QStyledItemDelegate):
          def initStyleOption(self, option, index):
              super(IconDelegate, self).initStyleOption(option, index)
              if option.features & QtWidgets.QStyleOptionViewItem.HasDecoration:
                  s = option.decorationSize
                  s.setWidth(option.rect.width())
                  option.decorationSize = s
      class Delegate(QtWidgets.QStyledItemDelegate):
          def __init__(self, parent=None):
              super(Delegate, self).__init__(parent=None)
          def initStyleOption(self, option, index):
              
      #        super(IconDelegate, self).initStyleOption(option, index)
              if index.column() == 6:
                  if option.features & QtWidgets.QStyleOptionViewItem.HasDecoration:
                      s = option.decorationSize
                      s.setWidth(option.rect.width())
                      option.decorationSize = s
          def createEditor(self, parent, option, index):
              editor = QtWidgets.QComboBox(parent)         
              return editor
          def setEditorData(self, editor, index):
              model = index.model()
              items = model.items
              text = items[index.row()][index.column()]
              editor.setCurrentText(text)
          def setModelData(self, editor, model, index):
              
              items = model.items
      #
      class TableView(QtWidgets.QTableView):
          def __init__(self, parent=None):
              super(TableView, self).__init__(parent=None)
              delegate = Delegate()
              #Here is the place of bug. Please try the two cases.
              self.setItemDelegateForColumn(6, delegate)
              self.setItemDelegateForColumn(11, IconDelegate())
              self.tableModel = TableModel(2, 15)
              self.setModel(self.tableModel)
          def keyPressEvent(self, event):
              if event.key() == QtCore.Qt.Key_1:
                  self.tableModel.insertRows(0)
                  
      class TableItem(object):
          def __init__(self,  parent=None):        
              self.root = False         self.word = ""
              self.alignment = QtCore.Qt.AlignCenter
              
              self.rule = ""
              self.foregroundcolor = QtGui.QColor(QtCore.Qt.black)
              self.backgroundcolor = QtGui.QColor(QtCore.Qt.white)
              self.font = QtGui.QFont("Meiryo", 14)
      class TableModel(QtCore.QAbstractTableModel):
        
          def __init__(self, row = 0, column = 0, parent = None):
              super(TableModel, self).__init__(parent = None)        
              self.items = [[TableItem() for c in range(column)] for r in range(row)]
              self.root = QtCore.QModelIndex()        
          def rowCount(self, parent=QtCore.QModelIndex()):        
              return len(self.items)
          def columnCount(self, parent=QtCore.QModelIndex()):       
              return 15
          def data(self, index, role = QtCore.Qt.DisplayRole):    
              if not index.isValid():
                  return None
              row = index.row()
              column = index.column()        
              if role == QtCore.Qt.DisplayRole:
                  item = self.items[row][column]
                  return item
          def headerData(self, section, orientation, role = QtCore.Qt.DisplayRole):
              if orientation == QtCore.Qt.Orientation.Horizontal:
                  if role == QtCore.Qt.DisplayRole:
                      return alphabet[section]
              return super(TableModel, self).headerData(section, orientation, role)
          def flags(self, index):        
              return QtCore.Qt.ItemFlag.ItemIsEditable|QtCore.Qt.ItemFlag.ItemIsEnabled|QtCore.Qt.ItemFlag.ItemIsSelectable
          def setData(self, index, value, role=QtCore.Qt.EditRole):        
              if role == QtCore.Qt.EditRole:       
                  row, column = index.row(), index.column()
              
                  self.items[row][column]  = value
                  self.dataChanged.emit(index, index)
                  return True
              elif role == QtCore.Qt.DisplayRole:             
                  row, column = index.row(), index.column()
                  self.items[row][column]  = value
                  self.dataChanged.emit(index, index)
                  return True
              elif role == QtCore.Qt.FontRole:
                  string = value.toString()
                  s = string.split(",")
                  font = s[0]
                  
                  self.dataChanged.emit(index, index)
                  return True
          def insertRows(self, position, rows=1, index=QtCore.QModelIndex()):   
              self.beginInsertRows(QtCore.QModelIndex(), position, position+rows-1)
              for row in range(rows):        
                  self.items.insert(position+row, [TableItem() for c in range(self.columnCount())])
              self.endInsertRows()
              self.emit(QtCore.SIGNAL("dataChanged(QModelIndex, QModelIndex)"), index, index)
              self.emit(QtCore.SIGNAL("layoutChanged()"))      
              return True
          def removeRows(self, position, rows=1, index=QtCore.QModelIndex()):
              self.beginRemoveRows(QtCore.QModelIndex(), position, position+rows-1)
              for row in range(rows):
                  self.items = self.items[:position] + \
                              self.items[position + rows:]
              self.emit(QtCore.SIGNAL("dataChanged(QModelIndex, QModelIndex)"), index, index)
              self.emit(QtCore.SIGNAL("layoutChanged()"))      
              return True
          
      def main():
          if QtWidgets.QApplication.instance() is not None:
              app = QtWidgets.QApplication.instance()
          else:
              app = QtWidgets.QApplication([])
          mainwindow = TableView()
          mainwindow.show()
          sys.exit(QtWidgets.QApplication.exec_())
      if __name__ == "__main__":
          main()

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            crmaurei Cristian Maureira-Fredes
            nori Harunori Fujimoto
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes