首页 > 解决方案 > QTableview checkitems,从对应的第二列获取值

问题描述

我有两个关于QTableView.

  1. 如何使 QTable 仅可编辑第二列值,而只读第一列?

  2. 如何获取被勾选项的索引,从而可以得到被勾选项对应的第二列的值?

    from PyQt5 import QtWidgets, QtGui
    
    class MyWidget(QtWidgets.QWidget):
    
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
            # selected items
            self.selected = []
            self.no       = []
    
            self.tableModel = QtGui.QStandardItemModel(self)
            self.tableModel.itemChanged.connect(self.itemChanged)
            # 
            item1 = QtGui.QStandardItem("file#1")
            item1.setCheckable(True)
            no1 = QtGui.QStandardItem("5.0")
            self.tableModel.appendRow([item1, no1])
            # 
            item2 = QtGui.QStandardItem("file#2")
            item2.setCheckable(True)
            no2 = QtGui.QStandardItem("23.0")
            self.tableModel.appendRow([item2, no2])
    
            self.mainLayout = QtWidgets.QVBoxLayout()
            self.setLayout(self.mainLayout)
    
            self.tableView = QtWidgets.QTableView()
            self.tableView.setModel(self.tableModel)
            self.mainLayout.addWidget(self.tableView)
    
            "First Question"
            """How to make table only editable second column, not firts:
               ex. can edit 23.0 or 5.0, but read only file names?
            """        
    
        def itemChanged(self, item):
            if item.checkState() != 0:
                if not item.text() in self.selected:
                    self.selected.append(item.text())
            else:
                if item.text() in self.selected:
                    self.selected.remove(item.text())
    
            print(self.selected)
    
            "Second Question"
            """How to get item checked index and to get the second column value:
               ex. file#2 has 23.0?
            """
    
            self.no.append(second column value) ****?
            print(self.no)
    
    def main():
        app = QtWidgets.QApplication([])
    
        mytable = MyWidget()
        mytable.show()
        app.exec_()
    
    if __name__ == "__main__":
        main()
    

标签: pythonpyqtpyqt5

解决方案


如何使 QTable 仅可编辑第二列值,而只读第一列?

有几种解决方案可以使整个列的项目只读/可编辑。

  • 修改标志,没有必要按照PyThagoras 的回答所建议的那样实现自定义模型,因为 QStandardItemModel 模型允许修改它们:

    # To make them editable:
    item.setEditable(True)
    # or
    # item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
    
    # To make them readonly:
    item.setEditable(False)
    # or
    # item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEditable)
    
  • 使用委托的编辑器,因为 QStandardItemModel 模型在默认情况下是可编辑的,因此仅足以确定第 0 列是不可编辑的,为此您不应生成编辑器:

    class ReadOnlyDelegate(QtWidgets.QStyledItemDelegate):
        def createEditor(self, parent, option, index):
            return
    
    delegate = ReadOnlyDelegate(self.tableView)
    self.tableView.setItemDelegateForColumn(0, delegate)
    

我更喜欢第二个选项,因为默认情况下它确定第一列是只读的。

如何获取被勾选项的索引,从而可以得到被勾选项对应的第二列的值?

通用方法是访问父亲,然后访问同一行但在第二列的儿子:

parent_item = item.parent()
if parent_item is not None:
    second_item = parent_item.child(item.row(), 1)
else:
    second_item = item.model().item(item.row(), 1)
print(second_item.text())

但在您的情况下,它可以简化为:

second_item = self.tableModel.item(item.row(), 1)
print(second_item.text())

推荐阅读