Модели служат для хранения информации, не сохраняют обзор.Если вы хотите настроить представление, вы должны использовать делегатов.По умолчанию, если вы сохраните его в роли CheckStateRole
, будет создан флажок, если вы сохраните его в DisplayRole
, он будет отображаться в виде текста, поэтому даже если вы сохраните виджеты, то будет отображаться __str__
, которыйпоказывает адрес памяти.
Что вам нужно сделать, это просто сохранить данные, то есть bool, значение и текст, а затем создать делегата, создав редактор во втором столбце и сделав его постоянным..
import sys
from PyQt4 import QtCore, QtGui
class PaletteTableModel(QtCore.QAbstractTableModel):
def __init__(self, cols=3,colors = [], parent = None):
super(PaletteTableModel, self).__init__(parent)
self.__colors = colors
self.__cols = cols
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.__colors)
def columnCount(self, parent=QtCore.QModelIndex()):
if parent.isValid():
return 0
return self.__cols
def appendRow(self, data):
self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
self.__colors.append(data[:])
self.endInsertRows()
def flags(self, index):
fl = QtCore.Qt.NoItemFlags
if index.isValid():
fl |= QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
if index.column() == 0:
fl |= QtCore.Qt.ItemIsUserCheckable
return fl
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
row = index.row()
col = index.column()
if 0 <= row < self.rowCount() and 0<= col < self.columnCount():
if role == QtCore.Qt.DisplayRole and 0 < col < self.columnCount():
return self.__colors[row][col]
elif role == QtCore.Qt.CheckStateRole and col == 0:
return QtCore.Qt.Checked if self.__colors[row][0] else QtCore.Qt.Unchecked
return None
def setData(self, index, value, role=QtCore.Qt.EditRole):
if not index.isValid():
return False
row = index.row()
col = index.column()
if role == QtCore.Qt.CheckStateRole and col == 0:
self.__colors[row][col] = value == QtCore.Qt.Checked
return True
elif role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole):
if 0 < index.column() < self.columnCount():
self.__colors[row][col] = value
return True
return False
class PaletteDelegate(QtGui.QStyledItemDelegate):
def paint(self, painter, option, index):
if index.column() == 1:
view = option.widget
if isinstance(view, QtGui.QTableView):
if not view.openPersistentEditor(index):
view.openPersistentEditor(index)
else:
super(PaletteDelegate, self).paint(painter, option, index)
def createEditor(self, parent, option, index):
if index.column() == 1:
editor = QtGui.QSlider(parent, minimum=10, maximum=30, orientation=QtCore.Qt.Horizontal)
editor.valueChanged.connect(self.commitEditor)
return editor
return super(PaletteDelegate, self).createEditor(parent, option, index)
def setEditorData(self, editor, index):
if index.column() == 1:
val = index.data()
if isinstance(val, QtCore.QVariant):
_, val = val.toInt()
editor.setValue(val)
else:
super(PaletteDelegate, self).setEditorData(editor, index)
def setModelData(self, editor, model, index):
if index.column() == 1:
model.setData(index, editor.value())
else:
super(PaletteDelegate, self).setModelData(editor,model, index)
def commitEditor(self):
editor = self.sender()
self.commitData.emit(editor)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
app.setStyle("plastique")
tableView = QtGui.QTableView()
tableView.show()
row, col = 6, 3
model = PaletteTableModel(cols=col, parent=tableView)
tableView.setModel(model)
tableView.setItemDelegate(PaletteDelegate(tableView))
for r in range(row):
data = [True, 20, 'TEST']
model.appendRow(data)
sys.exit(app.exec_())