Pyqt4 Model View - Adding Slider , CheckBox Line Edit in Table model

Deadly 提交于 2019-12-02 13:06:23

The models serve to keep information, do not keep the view. If you want to customize the view you should use delegates. By default if you save it in the CheckStateRole role, a checkbox will be created, if you save in the DisplayRole it will be displayed as text, so even if you save the widgets what is shown is the __str__ that shows the memory address.

What you should do is just save the data, that is, the bool, the value and the text, and then create a delegate by creating an editor in the second column and make it persistent.

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_())

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!