【Pyqt5】QTableView添加复选框的一种方法

QTableView添加复选框

网上查了下QTableView添加复选框有四种方法,都比较麻烦。

https://blog.csdn.net/liang19890820/article/details/50718340

后来看到QStandardltem有setCheckable勾选方法,就想着利用该方法,单独生成一列Checkbox显示。并在选中某一行时将Checkbox勾选上,在勾选Checkbox时自动将某一行选上。

本身Checkbox是否勾选与该行是否选择是没有关联的,要找到关联就需要借助于信号。

QItemSelectionModel在选择的单元格改变时会自动发出selectionChanged信号,所以只需要选择改变时通过槽函数OnSelectionChanged设置对应行的Checkbox。通过QItemSelection获取QModelIndex列表,然后遍历列表中所有的QModelIndex,设置对应的Checkbox状态

QModelIndexList indexes() const 选择范围的QModelIndex单元格列表

  for item in selectlist.indexes():
            rowNum = item.row()
            # 0:Qt.Unchecked, 1:Qt.PartiallyChecked, 2:Qt.Checked
            self.targetItemModel.item(rowNum, 0).setCheckState(Qt.Checked)

        for item in deselectlist.indexes():
            rowNum = item.row()
            self.targetItemModel.item(rowNum, 0).setCheckState(Qt.Unchecked)

void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)

QStandardItemModel在单元格改变时会自动发出itemChanged信号,设置槽函数OnCheckBoxItemChanged处理该信号就可以进行行的选择。

需要注意的是QStandardItem可以获得行号,tableView有函数可以直接选中指定行,但是没找到不选择中指定行的函数。

于是还得根据QStandardItem找到QModelIndex,再根据QModelIndex不选择某行,不选择某行的时候需要为QItemSelectionModel.Deselect|QItemSelectionModel.Rows,否则只能不选择第一个单元格。

QModelIndex indexFromItem(const QStandardItem *item) const 查询指定QStandardItem的QModelIndex

ModelIndex = self.targetItemModel.indexFromItem(item)
self.targetSelectModel.select(ModelIndex, QItemSelectionModel.Deselect|QItemSelectionModel.Rows)  

void itemChanged(QStandardItem *item)

 

【Pyqt5】QTableView添加复选框的一种方法_第1张图片

  def initTargetView(self):
        print('initTargetView')

        self.targetItemModel = QStandardItemModel()
        self.tableView.setModel(self.targetItemModel)

        #按照行选择,可选择多行
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setSelectionMode(QAbstractItemView.MultiSelection)

        #初始化QStandardItemModel
        self.LoadTarget()  

        #需要初始化设置QItemSelectionModel
        self.targetSelectModel = QItemSelectionModel(self.targetItemModel)
        self.tableView.setSelectionModel(self.targetSelectModel)
  

        self.pushButton_add.clicked.connect(self.CreateTarget)
        self.pushButton_modify.clicked.connect(self.ModifyTarget)
        self.pushButton_del.clicked.connect(self.DeleteTarget)
        self.tableView.doubleClicked.connect(self.OnTargetDoubleClicked)
        self.targetSelectModel.selectionChanged.connect(self.OnSelectionChanged)
        self.targetItemModel.itemChanged.connect(self.OnCheckBoxItemChanged)
     def OnSelectionChanged(self,selectlist, deselectlist):
        print('OnSelectionChanged')
        #选择项改变后,遍历选择的行,将第一列设置为Qt.Checked状态,遍历未选择的行,将未选择的行设置为Qt.Unchecked状态。
        for item in selectlist.indexes():
            rowNum = item.row()
            # 0:Qt.Unchecked, 1:Qt.PartiallyChecked, 2:Qt.Checked
            self.targetItemModel.item(rowNum, 0).setCheckState(Qt.Checked)

        for item in deselectlist.indexes():
            rowNum = item.row()
            self.targetItemModel.item(rowNum, 0).setCheckState(Qt.Unchecked)

    def OnCheckBoxItemChanged(self, item):
        print('OnCheckBoxItemChanged')
        #对于itemChanged的单元格,获取行的行号和索引,如果该行的checkState为Checked则选择整行,如果checkState为Unchecked,则整行变为不选择。
        rowNum = item.row()
        
        ModelIndex = self.targetItemModel.indexFromItem(item)
        
        if self.targetItemModel.item(rowNum,0).checkState() == Qt.Checked:
            self.tableView.selectRow(rowNum)

        elif self.targetItemModel.item(rowNum,0).checkState() == Qt.Unchecked:
            self.targetSelectModel.select(ModelIndex, QItemSelectionModel.Deselect|QItemSelectionModel.Rows)  




    def LoadTarget(self):
        print('LoadTarget')
        #从数据库获取Target信息,类似表格表格数据
        self.targetlist = self.returnTargetInfo()

        RowNum = len(self.targetlist)    
        #每次导入时将Model中的数据清除,重新初始化
        self.targetItemModel.clear()
        #第一列没有名称,为CheckBox
        self.targetItemModel.setHorizontalHeaderLabels(('', '名称', '参数1', '参数2', '参数3'))
        self.tableView.verticalHeader().hide()  #列表头不显示
        self.tableView.horizontalHeader().setHighlightSections(False)   
        self.tableView.setColumnWidth(0,10)    #设置各列宽度
        self.tableView.setColumnWidth(1,30)
        self.tableView.setColumnWidth(2,115)
        self.tableView.setColumnWidth(3,85)
        self.tableView.setColumnWidth(4,40)

        for row in range(RowNum):
            #cell为第一列,不能编辑,有勾选框可以勾选
            cell = QStandardItem()   
            cell.setCheckable(True)   
            cell.setEditable(False)
            self.targetItemModel.setItem(row, 0, cell)

            for col in range(4):
                cell = QStandardItem(str(self.targetlist[row][col + 1]))
                cell.setEditable(False)
                self.targetItemModel.setItem(row, col+1, cell)

           self.tableView.show()

 

 

你可能感兴趣的:(PyQt5,原创)