I keep getting TypeError: 'list' object is not callable while implementing delegate setEditorData
-
wrote on 23 Oct 2021, 08:12 last edited by
Traceback (most recent call last):
File "D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\tabledelegate.py", line 28, in setEditorData
value = index.model().data(index, QtCore.Qt.EditRole)
TypeError: 'list' object is not callableThe editor Loads fine, but as soon as i double click the modelindex(any cell in the table view) it crashes
i referred
https://github.com/baoboa/pyqt5/blob/master/examples/itemviews/spinboxdelegate.py
https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.htmlif i implement only createEditor it works fine.
is it because i am setting list in model i am getting the TypeError? --
self.data_column.insert(position, [])
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, head_columns_names, head_rows_names, table_rows_count=int, table_columns_count=int): super(TableModel, self).__init__() self.headColStringsList = head_columns_names self.headRowStringsList = head_rows_names self.data = [] # this is just an empty data to use for row self.data_column = [] # this is just an empty data to use for column self.table_rows_count = table_rows_count self.table_columns_count = table_columns_count def rowCount(self, index=QtCore.QModelIndex): # as per the docs this method should return 0 if used for table return len(self.data) def columnCount(self, index=QtCore.QModelIndex()): # as per the docs this method should return 0 if used for table return len(self.data_column) def data(self, index=QtCore.QModelIndex, role=QtCore.Qt.DisplayRole): if index.isValid(): if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole: value = self.data[index.row()][index.column()] return str(value) def setData(self, index=QtCore.QModelIndex, value=QtCore.QVariant, role=QtCore.Qt.EditRole): if role == QtCore.Qt.EditRole: self.data[index.row()][index.column()] = value return True return False def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self.headColStringsList[section] if orientation == QtCore.Qt.Vertical: return self.headRowStringsList[section] def flags(self, index): return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable def insertRow(self, position, index=QtCore.QModelIndex()): self.insertRows(position, self.table_rows_count, index) def insertRows(self, position, rows, parent=QtCore.QModelIndex()): self.beginInsertRows(parent, position, position + rows - 1) for row in range(0, rows): # mention rows as per the column count self.data.insert(position, ["", "", "", "", ""]) self.endInsertRows() return True def insertColumn(self, position, index=QtCore.QModelIndex()): self.insertColumns(position, self.table_columns_count, index) def insertColumns(self, position, columns, parent=QtCore.QModelIndex()): self.beginInsertColumns(parent, position, position + columns - 1) for column in range(0, columns): # mention the column type here example [] (empty list) self.data_column.insert(position, []) self.endInsertColumns() return True
from PyQt5 import QtWidgets from PyQt5 import QtCore class TableDelegate(QtWidgets.QStyledItemDelegate): def __init__(self): super(TableDelegate, self).__init__() def createEditor(self, parent, option, index): editor = QtWidgets.QSpinBox(parent) editor.setMinimum(0) editor.setMaximum(100) return editor def setEditorData(self, editor, index): value = index.model().data(index, QtCore.Qt.EditRole) editor.setValue(value) def setModelData(self, editor, model, index): editor.interpretText() value = editor.value() model.setData(index, value, QtCore.Qt.EditRole) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) # https://stackoverflow.com/questions/30615090/pyqt-using-qtextedit-as-editor-in-a-qstyleditemdelegate?rq=1 # https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets from PyQt5 import QtCore from PyQt5 import QtGui from tabledelegate import TableDelegate import sys import json with open('configuration_file.json') as data: config = json.load(data) table_strings = config class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) # fetch the col header names self.table_col_names = [col for col in config.keys()] # creating row numbers with range self.table_row_names = [row for row in range(10)] # setup the table header rows and column names, and row and column count self.model = TableModel(head_columns_names=self.table_col_names, head_rows_names=self.table_row_names, table_rows_count=5, table_columns_count=5) self.delegate = TableDelegate() self.model.insertRow(0) # position of the inserted row self.model.insertColumn(0) # position of the inserted column self.ui.tableView.setModel(self.model) self.ui.tableView.setItemDelegate(self.delegate) # this option appends the spinbox delegate to whole row and column not just single modelindex # self.ui.tableView.setItemDelegateForColumn(3, self.delegate) # self.ui.tableView.setItemDelegateForRow(2, self.delegate) # signal to get data from row/col # self.ui.tableView.clicked.connect(self.index_selection) # caveat: only one row value can be returned at a time. for loop can be added later. # return the selected value from the tableview def index_selection(self): index = self.ui.tableView.selectedIndexes() print(index[0].row(), index[0].column()) value = index[0].data() print(value) return value app = QtWidgets.QApplication(sys.argv) app.setStyle('windows') window = TableView() window.show() sys.exit(app.exec_())
-
Traceback (most recent call last):
File "D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\tabledelegate.py", line 28, in setEditorData
value = index.model().data(index, QtCore.Qt.EditRole)
TypeError: 'list' object is not callableThe editor Loads fine, but as soon as i double click the modelindex(any cell in the table view) it crashes
i referred
https://github.com/baoboa/pyqt5/blob/master/examples/itemviews/spinboxdelegate.py
https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.htmlif i implement only createEditor it works fine.
is it because i am setting list in model i am getting the TypeError? --
self.data_column.insert(position, [])
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, head_columns_names, head_rows_names, table_rows_count=int, table_columns_count=int): super(TableModel, self).__init__() self.headColStringsList = head_columns_names self.headRowStringsList = head_rows_names self.data = [] # this is just an empty data to use for row self.data_column = [] # this is just an empty data to use for column self.table_rows_count = table_rows_count self.table_columns_count = table_columns_count def rowCount(self, index=QtCore.QModelIndex): # as per the docs this method should return 0 if used for table return len(self.data) def columnCount(self, index=QtCore.QModelIndex()): # as per the docs this method should return 0 if used for table return len(self.data_column) def data(self, index=QtCore.QModelIndex, role=QtCore.Qt.DisplayRole): if index.isValid(): if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole: value = self.data[index.row()][index.column()] return str(value) def setData(self, index=QtCore.QModelIndex, value=QtCore.QVariant, role=QtCore.Qt.EditRole): if role == QtCore.Qt.EditRole: self.data[index.row()][index.column()] = value return True return False def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self.headColStringsList[section] if orientation == QtCore.Qt.Vertical: return self.headRowStringsList[section] def flags(self, index): return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable def insertRow(self, position, index=QtCore.QModelIndex()): self.insertRows(position, self.table_rows_count, index) def insertRows(self, position, rows, parent=QtCore.QModelIndex()): self.beginInsertRows(parent, position, position + rows - 1) for row in range(0, rows): # mention rows as per the column count self.data.insert(position, ["", "", "", "", ""]) self.endInsertRows() return True def insertColumn(self, position, index=QtCore.QModelIndex()): self.insertColumns(position, self.table_columns_count, index) def insertColumns(self, position, columns, parent=QtCore.QModelIndex()): self.beginInsertColumns(parent, position, position + columns - 1) for column in range(0, columns): # mention the column type here example [] (empty list) self.data_column.insert(position, []) self.endInsertColumns() return True
from PyQt5 import QtWidgets from PyQt5 import QtCore class TableDelegate(QtWidgets.QStyledItemDelegate): def __init__(self): super(TableDelegate, self).__init__() def createEditor(self, parent, option, index): editor = QtWidgets.QSpinBox(parent) editor.setMinimum(0) editor.setMaximum(100) return editor def setEditorData(self, editor, index): value = index.model().data(index, QtCore.Qt.EditRole) editor.setValue(value) def setModelData(self, editor, model, index): editor.interpretText() value = editor.value() model.setData(index, value, QtCore.Qt.EditRole) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) # https://stackoverflow.com/questions/30615090/pyqt-using-qtextedit-as-editor-in-a-qstyleditemdelegate?rq=1 # https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets from PyQt5 import QtCore from PyQt5 import QtGui from tabledelegate import TableDelegate import sys import json with open('configuration_file.json') as data: config = json.load(data) table_strings = config class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) # fetch the col header names self.table_col_names = [col for col in config.keys()] # creating row numbers with range self.table_row_names = [row for row in range(10)] # setup the table header rows and column names, and row and column count self.model = TableModel(head_columns_names=self.table_col_names, head_rows_names=self.table_row_names, table_rows_count=5, table_columns_count=5) self.delegate = TableDelegate() self.model.insertRow(0) # position of the inserted row self.model.insertColumn(0) # position of the inserted column self.ui.tableView.setModel(self.model) self.ui.tableView.setItemDelegate(self.delegate) # this option appends the spinbox delegate to whole row and column not just single modelindex # self.ui.tableView.setItemDelegateForColumn(3, self.delegate) # self.ui.tableView.setItemDelegateForRow(2, self.delegate) # signal to get data from row/col # self.ui.tableView.clicked.connect(self.index_selection) # caveat: only one row value can be returned at a time. for loop can be added later. # return the selected value from the tableview def index_selection(self): index = self.ui.tableView.selectedIndexes() print(index[0].row(), index[0].column()) value = index[0].data() print(value) return value app = QtWidgets.QApplication(sys.argv) app.setStyle('windows') window = TableView() window.show() sys.exit(app.exec_())
wrote on 23 Oct 2021, 08:42 last edited by@blossomsg The problem is that the attribute
self.data = []
is hiding the methoddef data(self, index=QtCore.QModelIndex, role=QtCore.Qt.DisplayRole):
. Solution changesself.data = []
toself._data = []
-
Traceback (most recent call last):
File "D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\tabledelegate.py", line 28, in setEditorData
value = index.model().data(index, QtCore.Qt.EditRole)
TypeError: 'list' object is not callableThe editor Loads fine, but as soon as i double click the modelindex(any cell in the table view) it crashes
i referred
https://github.com/baoboa/pyqt5/blob/master/examples/itemviews/spinboxdelegate.py
https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.htmlif i implement only createEditor it works fine.
is it because i am setting list in model i am getting the TypeError? --
self.data_column.insert(position, [])
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, head_columns_names, head_rows_names, table_rows_count=int, table_columns_count=int): super(TableModel, self).__init__() self.headColStringsList = head_columns_names self.headRowStringsList = head_rows_names self.data = [] # this is just an empty data to use for row self.data_column = [] # this is just an empty data to use for column self.table_rows_count = table_rows_count self.table_columns_count = table_columns_count def rowCount(self, index=QtCore.QModelIndex): # as per the docs this method should return 0 if used for table return len(self.data) def columnCount(self, index=QtCore.QModelIndex()): # as per the docs this method should return 0 if used for table return len(self.data_column) def data(self, index=QtCore.QModelIndex, role=QtCore.Qt.DisplayRole): if index.isValid(): if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole: value = self.data[index.row()][index.column()] return str(value) def setData(self, index=QtCore.QModelIndex, value=QtCore.QVariant, role=QtCore.Qt.EditRole): if role == QtCore.Qt.EditRole: self.data[index.row()][index.column()] = value return True return False def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self.headColStringsList[section] if orientation == QtCore.Qt.Vertical: return self.headRowStringsList[section] def flags(self, index): return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable def insertRow(self, position, index=QtCore.QModelIndex()): self.insertRows(position, self.table_rows_count, index) def insertRows(self, position, rows, parent=QtCore.QModelIndex()): self.beginInsertRows(parent, position, position + rows - 1) for row in range(0, rows): # mention rows as per the column count self.data.insert(position, ["", "", "", "", ""]) self.endInsertRows() return True def insertColumn(self, position, index=QtCore.QModelIndex()): self.insertColumns(position, self.table_columns_count, index) def insertColumns(self, position, columns, parent=QtCore.QModelIndex()): self.beginInsertColumns(parent, position, position + columns - 1) for column in range(0, columns): # mention the column type here example [] (empty list) self.data_column.insert(position, []) self.endInsertColumns() return True
from PyQt5 import QtWidgets from PyQt5 import QtCore class TableDelegate(QtWidgets.QStyledItemDelegate): def __init__(self): super(TableDelegate, self).__init__() def createEditor(self, parent, option, index): editor = QtWidgets.QSpinBox(parent) editor.setMinimum(0) editor.setMaximum(100) return editor def setEditorData(self, editor, index): value = index.model().data(index, QtCore.Qt.EditRole) editor.setValue(value) def setModelData(self, editor, model, index): editor.interpretText() value = editor.value() model.setData(index, value, QtCore.Qt.EditRole) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) # https://stackoverflow.com/questions/30615090/pyqt-using-qtextedit-as-editor-in-a-qstyleditemdelegate?rq=1 # https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets from PyQt5 import QtCore from PyQt5 import QtGui from tabledelegate import TableDelegate import sys import json with open('configuration_file.json') as data: config = json.load(data) table_strings = config class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) # fetch the col header names self.table_col_names = [col for col in config.keys()] # creating row numbers with range self.table_row_names = [row for row in range(10)] # setup the table header rows and column names, and row and column count self.model = TableModel(head_columns_names=self.table_col_names, head_rows_names=self.table_row_names, table_rows_count=5, table_columns_count=5) self.delegate = TableDelegate() self.model.insertRow(0) # position of the inserted row self.model.insertColumn(0) # position of the inserted column self.ui.tableView.setModel(self.model) self.ui.tableView.setItemDelegate(self.delegate) # this option appends the spinbox delegate to whole row and column not just single modelindex # self.ui.tableView.setItemDelegateForColumn(3, self.delegate) # self.ui.tableView.setItemDelegateForRow(2, self.delegate) # signal to get data from row/col # self.ui.tableView.clicked.connect(self.index_selection) # caveat: only one row value can be returned at a time. for loop can be added later. # return the selected value from the tableview def index_selection(self): index = self.ui.tableView.selectedIndexes() print(index[0].row(), index[0].column()) value = index[0].data() print(value) return value app = QtWidgets.QApplication(sys.argv) app.setStyle('windows') window = TableView() window.show() sys.exit(app.exec_())
wrote on 23 Oct 2021, 08:43 last edited by JonB@blossomsg
You do not say, but I assume you insert some row(s) after__init__()
and before editing.Start by sorting out your override of
insertRow()
, which is wrong, and if being called may be the cause of your error message. You attempt to addself.table_rows_count
new rows, which is quite incorrect. Either make it pass1
for that instead, or remove your override completely (recommended), since the base definition will call yourinsertRows()
correctly for you. Exactly the same applies to your definition ofinsertColumn()
.Does this perchance resolve your issue?
UPDATE
@eyllanesc has noticed your naming clash (good spot! one of the nasty gotchas in Python), which does indeed need changing, and would cause the text of the error you see. However, you will also need to make the changes I mentioned. -
@blossomsg The problem is that the attribute
self.data = []
is hiding the methoddef data(self, index=QtCore.QModelIndex, role=QtCore.Qt.DisplayRole):
. Solution changesself.data = []
toself._data = []
wrote on 23 Oct 2021, 13:26 last edited by@eyllanesc
Thank You That fixed my above error
that means i am heading in the right direction.
Below is the new error. I tried int()Traceback (most recent call last): File "D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\tabledelegate.py", line 29, in setEditorData editor.setValue(value) TypeError: setValue(self, int): argument 1 has unexpected type 'str'
Hey @JonB
but I assume you insert some row(s) after init() and before editing.
Sorry did not get you over hereI guess this what you are saying -- i should remove the
insertRow
andinsertColumn
altogether or just give 1 in row number
Start by sorting out your override of insertRow() - Either make it pass 1 or remove your override completely (recommended)def insertRow(self, position, index=QtCore.QModelIndex()): self.insertRows(position, 1, index)
So if i want to more number of cols and rows i should directly update in the model methods/function
insertRow
andinsertColumn
?
I created an argument for convenience to edit from outside
What is the correct way? -
@eyllanesc
Thank You That fixed my above error
that means i am heading in the right direction.
Below is the new error. I tried int()Traceback (most recent call last): File "D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\tabledelegate.py", line 29, in setEditorData editor.setValue(value) TypeError: setValue(self, int): argument 1 has unexpected type 'str'
Hey @JonB
but I assume you insert some row(s) after init() and before editing.
Sorry did not get you over hereI guess this what you are saying -- i should remove the
insertRow
andinsertColumn
altogether or just give 1 in row number
Start by sorting out your override of insertRow() - Either make it pass 1 or remove your override completely (recommended)def insertRow(self, position, index=QtCore.QModelIndex()): self.insertRows(position, 1, index)
So if i want to more number of cols and rows i should directly update in the model methods/function
insertRow
andinsertColumn
?
I created an argument for convenience to edit from outside
What is the correct way?wrote on 23 Oct 2021, 13:30 last edited by eyllanesc@blossomsg The explanation is simple: QSpinBox expects an integer but your model appears to be a list of strings causing the error. Correct for data type agreement. By example change to:
self.data.insert(position, [0, 0, 0, 0, 0])
-
wrote on 25 Oct 2021, 13:06 last edited by
I have really learnt alot
Thank you @eyllanesc
1/6