Pyqt4模型视图-在表格模型中添加滑块,复选框行编辑

时间:2018-10-08 10:03:20

标签: python tableview pyqt4 model-view

我正在使用ui,如下图所示。

在 第一栏我有一个复选框, 第二列我有一个滑块, 第三条纯文字

应用于功能的滑块值。结果将显示在第三列中。

我看不到滑块而不是复选框

输出显示在图像中

代码:

from PyQt4 import QtGui, QtCore, uic
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class PaletteTableModel(QtCore.QAbstractTableModel):
    def __init__(self, colors = [[]], parent = None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self.__colors = colors
    def rowCount(self, parent):
        return len(self.__colors)  
    def columnCount(self, parent):
        return len(self.__colors[0])
    def flags(self, index):
        if not index.isValid():
            return None
        if index.column() == 0:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role):        
        row = index.row()
        col = index.column()
        if role == QtCore.Qt.DisplayRole:
            return '{0}'.format(self.__colors[row][col])
        elif role == Qt.CheckStateRole and col==0:
            return QPersistentModelIndex(index)
        else:
            return None
    def setData(self, index, value, role=Qt.EditRole):
        if not index.isValid():
            return False
        if role == Qt.CheckStateRole:
            if index.column() == 0:
                if self.__colors[index.row()][index.column()].isChecked():
                    return QtCore.Qt.Checked
                else:
                    return QtCore.Qt.Unchecked   

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    app.setStyle("plastique")

    tableView = QtGui.QTableView()
    tableView.show()

    row = 6
    col = 3
    table_data = []
    for row in range(row):
        data = [None,None,None]
        #Checkbox
        c1 = QCheckBox("c"+str(row))
        c1.setChecked(True)
        data[0] = c1

        #slider
        s1 = QSlider(Qt.Horizontal)
        s1.setMinimum(10)
        s1.setMaximum(30)
        s1.setValue(20)
        data[1] = s1   

        #text
        data[2] = 'TEST'
        table_data.append(data)


    model = PaletteTableModel(table_data)    
    tableView.setModel(model)

    sys.exit(app.exec_())

UI:

Sceen shot of ui

1 个答案:

答案 0 :(得分:1)

模型用于保留信息,而不保留视图。如果要自定义视图,则应使用委托。默认情况下,如果将其保存为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_())

enter image description here