insertColumns (QAbstractTableModel) does not work correctly)
Encountered a problem: when trying to add a column after adding it N-rows(in my example 2), it turns out that:
Fig.1. Added 2 lines, until everything is OK
Fig.2. After adding 1 columns. The column was added by shifting the existing ones to the right, but pay attention to 2 column rows 1 and 2. I've been fighting this all night, until nothing happens. I can understand.
import sys
from PyQt5.QtWidgets import QApplication, QTableView, QPushButton
from PyQt5.QtCore import QAbstractTableModel
from PyQt5.QtCore import Qt, QModelIndex
from PyQt5.QtGui import QPixmap, QImage, QIcon, QColor
import random
data = [[random.randint(1, 100) for i in range(5)] for i in range(5)]
headers = [
'Column 1',
'Column 2',
'Column 3',
'Column 4',
'Column 5'
]
class TestModel(QAbstractTableModel):
def __init__(self, data=[[]], headers=[], parent=None):
super().__init__(parent)
self.__data = data
self.__headers = headers
self.__image_file = 'Notepad/icons/save_file.png'
self.getPixmap()
def getPixmap(self):
try:
with open(self.__image_file):
image = QImage(self.__image_file)
self.__pixmap = QPixmap(image)
except FileNotFoundError:
self.__pixmap = QPixmap(26, 26)
self.__pixmap.fill(QColor('green'))
print(self.__pixmap)
def rowCount(self, parent=QModelIndex()):
return len(self.__data)
def columnCount(self, parent=QModelIndex()):
return len(self.__data[0])
def flags(self, index):
return Qt.ItemIsEnabled|Qt.ItemIsSelectable|Qt.ItemIsEditable
def data(self, index, role):
if role == Qt.DisplayRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.EditRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.ToolTipRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.DecorationRole:
icon = QIcon(self.__pixmap)
return icon
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.EditRole:
row = index.row()
column = index.column()
self.__data[row][column] = value
self.dataChanged.emit(index, index)
return True
return False
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
if section < len(self.__headers):
return self.__headers[section]
else:
return 'Not implemented'
else:
return 'Row №' + str(section + 1)
def insertRows(self, position, rows, parent=QModelIndex()):
self.beginInsertRows(parent, position, position + rows - 1)
default_row = ['New row' for i in range(self.columnCount(None))]
for j in range(rows):
self.__data.insert(position, default_row)
self.endInsertRows()
return True
def insertColumns(self, position, columns, parent=QModelIndex()):
self.beginInsertColumns(parent, position, position + columns - 1)
for row in self.__data:
for i in range(columns):
row.insert(position, 'New col')
self.endInsertColumns()
return True
if __name__ == '__main__':
app = QApplication(sys.argv)
model = TestModel(data, headers)
table_view = QTableView()
table_view.setModel(model)
table_view.show()
table_view.resize(700, 300)
button1 = QPushButton('Add col')
button1.clicked.connect(lambda: model.insertColumns(0, 1))
button1.show()
button1.move(100, 100)
button2 = QPushButton('Add row')
button2.clicked.connect(lambda: model.insertRows(0, 2))
button2.show()
button2.move(100, 200)
sys.exit(app.exec_())
2
1 answers
Try this way:
import sys
import random
from PyQt5.QtWidgets import QApplication, QTableView, QPushButton, \
QWidget, QGridLayout
from PyQt5.QtCore import QAbstractTableModel, Qt, QModelIndex
from PyQt5.QtGui import QPixmap, QImage, QIcon, QColor
class TestModel(QAbstractTableModel):
def __init__(self, data=[[]], headers=[], parent=None):
super().__init__(parent)
self.__data = data
self.__headers = headers
self.__image_file = 'Ok.png' # 'Notepad/icons/save_file.png'
self.getPixmap()
def getPixmap(self):
try:
with open(self.__image_file):
image = QImage(self.__image_file)
self.__pixmap = QPixmap(image)
except FileNotFoundError:
self.__pixmap = QPixmap(26, 26)
self.__pixmap.fill(QColor('green'))
print(self.__pixmap)
def rowCount(self, parent=QModelIndex()):
return len(self.__data)
def columnCount(self, parent=QModelIndex()):
return len(self.__data[0])
def flags(self, index):
return Qt.ItemIsEnabled|Qt.ItemIsSelectable|Qt.ItemIsEditable
def data(self, index, role):
if role == Qt.DisplayRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.EditRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.ToolTipRole:
row = index.row()
column = index.column()
return self.__data[row][column]
if role == Qt.DecorationRole:
icon = QIcon(self.__pixmap)
return icon
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.EditRole:
row = index.row()
column = index.column()
self.__data[row][column] = value
self.dataChanged.emit(index, index)
return True
return False
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
if section < len(self.__headers):
return self.__headers[section]
else:
return 'Not implemented'
else:
return 'Row №' + str(section + 1)
def insertRows(self, position, rows, parent=QModelIndex()):
#print(f'\nrows={rows}, position={position} ---------------')
self.beginInsertRows(parent, position, position + rows - 1)
#default_row = [f'row{i}' for i in range(self.columnCount(None))]
#print(f'default_row={default_row} ===============')
for j in range(rows):
default_row = [f'row{i}-{j}' for i in range(self.columnCount(None))]
self.__data.insert(position, default_row)
self.endInsertRows()
return True
'''
def insertColumns222(self, position, columns, parent=QModelIndex()):
self.beginInsertColumns(parent, position, position + columns - 1)
for row in self.__data:
for i in range(columns):
row.insert(position, f'New col: {row}-{i}')
self.endInsertColumns()
return True
'''
# +++
def insertColumns(self, position, columns, parent=QModelIndex()):
self.beginInsertColumns(parent, position, position + columns - 1)
""" self.beginInsertColumns(index, first, last) """
rowCount = len(self.__data)
#print(f' rowCount={rowCount}, columns={columns}')
for i in range(columns):
#print(f' columns={i}')
for j in range(rowCount): # Преребираем Строки
#print(f' rowCount={j}, ?? {self.__data[j]}')
self.__data[j].insert(position, "new cell")
self.endInsertColumns()
return True
class MyWindow(QWidget):
def __init__(self):
super().__init__()
data = [[random.randint(1, 100) for i in range(5)] for i in range(5)]
headers = ['Column 1', 'Column 2', 'Column 3', 'Column 4', 'Column 5']
self.table_view = QTableView()
self.model = TestModel(data, headers) # MyTableModel(data, headers)
self.table_view.setModel(self.model)
button1 = QPushButton('Add col')
button1.clicked.connect(lambda: self.model.insertColumns(0, 1))
button2 = QPushButton('Add row')
button2.clicked.connect(lambda: self.model.insertRows(0, 2)) # 2 ?
grid = QGridLayout(self)
grid.addWidget(self.table_view, 0, 0, 1, 2)
grid.addWidget(button1, 1, 0)
grid.addWidget(button2, 1, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.resize(700, 300)
w.show()
sys.exit(app.exec_())
0
Author: S. Nick, 2021-01-22 00:09:55