代码之家  ›  专栏  ›  技术社区  ›  Mendel Reis

QItemDelegate复选框

  •  0
  • Mendel Reis  · 技术社区  · 7 年前

    所以,我在Maya中使用python和PySide2来定制工具。

    我有一个模型(QTableModel)和一个QTableView。

    模型中的每一行都有一组信息和一个复选框。

    我需要做一个QItemDelegate并将其用作复选框。没关系。我很难知道是否检查了该代表。

    我迭代模型以获取其数据(将其存储在节点中的Maya场景中)

        data = []
        rows = self.rowCount(1) #self is the model in this snnipet
        for row in range(rows):
            array = []
            for column in range (6): #6 for the fixed number of columns
                info = index.data()
                array.append(index.data())
            data.append(array)
    

    每行中的第一项恰好是一个复选框(委托)。在最后一个数据数组中,我最终得到了实际的QItemDelegate对象,而我真的想得到它的状态,无论是否选中,但它没有isChecked()方法。

    关于如何做到这一点的想法?

    非常感谢你!

    ########编辑1

    因此,模型确实具有注释中提到的标志:

    def flags(self, index):
            return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
    

    我想我是做错了代表,我承认,我在网上发现了这个snnipet,我正在努力理解它。。。。但事情是这样的:

    class CBDelegate(QItemDelegate):
    
    def __init__(self, parent):
    
        QItemDelegate.__init__(self, parent)
    
    
    def paint(self, painter, option, index):
    
        self.cb = QCheckBox()
    
        try:
            self.cb.setChecked(index.data())
        except:
            pass
    
        if not self.parent().indexWidget(index):
            self.parent().setIndexWidget(index, self.cb)
    

    然后,在TableView中:

     self.setItemDelegateForColumn(0, CBDelegate(self))
    

    有帮助吗?(如果你有maya 2017,我可以给你完整的代码……这有点乱,因为我把它作为一个学习练习!

    非常感谢。

    ############编辑2

    表视图:

    class Table(QTableView):
        def __init__(self, *args, **kwargs):
            QTableView.__init__(self, *args, **kwargs)
    
            # Set the delegate for column 0 of our table
            #self.setItemDelegateForColumn(6, ButtonDelegate(self)) #problem for another time
            self.setItemDelegateForColumn(0, CBDelegate(self))
    

    型号:

    class Model(QtCore.QAbstractTableModel):
    
        def __init__(self, cycles = [[]], headers = [], parent = None):
            QtCore.QAbstractTableModel.__init__(self, parent)
    
            self.cycles = cycles
            self.headers = headers
    
        def rowCount(self, parent):
    
            return len(self.cycles)
    
        def columnCount(self, parent):
            return len(self.cycles[0])
    
        def flags(self, index):
            return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
    
        def data(self, index, role):
    
            if role == QtCore.Qt.DisplayRole:
    
                row = index.row()
                column = index.column()
                value = self.cycles[row][column]
                return value
    
            if role == QtCore.Qt.EditRole:
    
                row = index.row()
                column = index.column()
                return self.cycles[row][column]
    
            if (role == QtCore.Qt.TextAlignmentRole):
                return QtCore.Qt.AlignCenter;
    
        def setData(self, index, value, role = QtCore.Qt.EditRole):
    
            change = False
    
            if role == QtCore.Qt.EditRole:
    
                row = index.row()
                column = index.column()
    
                value = value
    
                if (column == 1) or (column == 4):
                    try:
                        str(value)
                        change = True
                    except:
                        pm.warning("Not a valid name")
                        change = False
                elif (column == 2):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid frame")
                        change = False
                elif (column == 3):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid frame")
                        change = False
    
                elif (column == 5):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid version number")
                        change = False
    
                if change:
                    self.cycles[row][column] = value
                    self.dataChanged.emit(row, column)
                    return True
    
                return False            
    
        def headerData(self, section, orientation, role):
    
            if role == QtCore.Qt.DisplayRole:
    
                if orientation == QtCore.Qt.Horizontal:
                    return self.headers[section]
    
        def insertRows(self, position, rows, values = [] , parent = QtCore.QModelIndex()):
    
    
            self.beginInsertRows(parent, position, position+rows-1)
    
            self.cycles.insert(position, values)
    
            self.endInsertRows()
    
            self.getData()
    
    
    
        def getData(self):
    
            rows = self.rowCount(1)
    
            data = []
    
            for row in range(rows):
                array = []
                for column in range (6):
                    index = self.index(row, column)
                    info = index.data()
    
                    if type(info) == bool:
                        array.append(info)
    
                    elif type(info) == QItemDelegate:
                        val_is_checked = index.data(QtCore.Qt.CheckStateRole) != QtCore.Qt.Unchecked
                        array.append(val_is_checked)
    
                    else:
                        info = str(info)
                        array.append(info)
    
                array.append("del")
                data.append(array)
    
            dic = {}
            for item in data:
                dic[item[1]]=item
    
            for key in dic:
                print key, dic[key]
    
    
            #this from pickle
            #newData = data2String(dic)
            # and this is what I wanna save inside Maya
            #pm.setAttr("cycleAnimationListNode.cycles", newData)
    

    代理位于上面的编辑1中。

    那么我想您仍然需要周期和标题来启动此模型:

    headers = ["Select", "  Cycle Name  ", " Start ", "  End  ", "Info", "Version", " Del "]
    
    cycles = [[False,"idle","1","70","cool information","0", "deleteBtnPlaceHolder"]]
    

    我希望这样做。

    非常感谢。

    #####编辑3

    我在模型中有此自定义方法:

    def getData(self):
            rows = self.rowCount(1)
            data = []
            for row in range(rows):
                array = []
                for column in range (6):
                    index = self.index(row, column)
                    info = index.data()
                    array.append(info)              
                data.append(array)
    
            dic = {}
            for item in data:
                dic[item[1]]=item
    
            print ""
            print "data:"
            print ''
            for key in dic:
                print(key, dic[key])
    

    我使用它将模型转换为字典,以便将其序列化并存储为Autodesk Maya中节点的字符串属性。它运行正常,但它从第一列获得的信息总是没有。我必须以不同的方式检索它吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   eyllanesc Yonghwan Shin    7 年前

    如果要显示 QCheckBox ,只需启用标志 Qt::ItemIsUserCheckable 此外,您还必须通过 setData() ,因为在您的代码中,信息丢失,因为存储在以下部分中的显示了经过这些修改的模型:

    更新:

    以前禁用返回角色的数据方法 Qt::DisplayRole 对于第一列,因为它将文本放置在表中,这对我来说是不必要的,现在我启用了它,但为了不显示文本,我放置了一个删除文本的委托

    from PySide2.QtWidgets import *
    from PySide2.QtCore import *
    
    class Model(QAbstractTableModel):
        def __init__(self, cycles = [[]], headers = [], parent = None):
            QAbstractTableModel.__init__(self, parent)
            self.cycles = cycles
            self.headers = headers
            self.values_checked = []
    
        def rowCount(self, parent):
            return len(self.cycles)
    
        def columnCount(self, parent):
            return len(self.cycles[0])
    
        def flags(self, index):
            fl = Qt.ItemIsEnabled | Qt.ItemIsSelectable 
            if index.column() == 0:
                fl |= Qt.ItemIsUserCheckable
            else:
                fl |= Qt.ItemIsEditable
            return fl
    
        def data(self, index, role):
            if not index.isValid():
                return 
            row = index.row()
            column = index.column()
    
            if role == Qt.DisplayRole:
                value = self.cycles[row][column]
                return value
    
            elif role == Qt.TextAlignmentRole:
                return Qt.AlignCenter;
    
            elif role == Qt.CheckStateRole and column==0:
                return Qt.Checked if self.cycles[row][column] else Qt.Unchecked
    
    
        def setData(self, index, value, role = Qt.EditRole):
            change = False
            row = index.row()
            column = index.column()
    
            if role == Qt.CheckStateRole:
                value =  value != Qt.Unchecked
                change = True
            if role == Qt.EditRole:
                if (column == 1) or (column == 4):
                    try:
                        str(value)
                        change = True
                    except:
                        pm.warning("Not a valid name")
                        change = False
                elif (column == 2):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid frame")
                        change = False
                elif (column == 3):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid frame")
                        change = False
    
                elif (column == 5):
                    try:
                        int(value)
                        change = True
                    except:
                        pm.warning("Not a valid version number")
                        change = False
            if change:
                self.cycles[row][column] = value
                self.dataChanged.emit(row, column)
                return True
            return False            
    
        def headerData(self, section, orientation, role):
            if role == Qt.DisplayRole:
                if orientation == Qt.Horizontal:
                    return self.headers[section]
    
        def insertRows(self, position, rows, values = [] , parent =QModelIndex()):
            self.beginInsertRows(parent, position, position+rows-1)
            self.cycles.insert(position, values)
            self.endInsertRows()
            self.getData()
    
        def roleNames(self):
            roles = QAbstractTableModel.roleNames(self)
            roles["Checked"] = Qt.CheckStateRole
            return roles
    
    
        def getData(self):
                rows = self.rowCount(1)
                data = []
                for row in range(rows):
                    array = []
                    for column in range (6):
                        index = self.index(row, column)
                        info = index.data()
                        array.append(info)              
                    data.append(array)
    
                dic = {}
                for item in data:
                    dic[item[1]]=item
    
                print("")
                print("data:")
                print('')
                for key in dic:
                    print(key, dic[key])
    
    
    class EmptyDelegate(QStyledItemDelegate):
        def paint(self, painter, option, index):
            opt = QStyleOptionViewItem(option)
            self.initStyleOption(opt, index)
            opt.text = ""
            QApplication.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
    
    
    if __name__ == '__main__':
        import sys
    
        app = QApplication(sys.argv)
        w = QTableView()
        w.setItemDelegateForColumn(0, EmptyDelegate(w))
        headers = ["Select", "  Cycle Name  ", " Start ", "  End  ", "Info", "Version", " Del "]
        cycles = [[True,"idle","1","70","cool information","0", "deleteBtnPlaceHolder"]]
        model = Model(cycles, headers)
        w.setModel(model)
        w.show()
        sys.exit(app.exec_())