[Pyqt5] A method of adding check boxes to QTableView

QTableView add checkbox

There are four ways to add checkboxes to QTableView, all of which are troublesome.

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

Later I saw that QStandardltem has a setCheckable check method, so I wanted to use this method to generate a list of Checkbox displays. And check the Checkbox when you select a row, and automatically select a row when you check the Checkbox.

Whether the Checkbox itself is checked is not related to whether the row is selected. To find the connection, you need to rely on signals.

QItemSelectionModel will automatically send the selectionChanged signal when the selected cell is changed , so it is only necessary to set the Checkbox of the corresponding row through the slot function OnSelectionChanged when the selection changes . Get the QModelIndex list through QItemSelection, then traverse all QModelIndex in the list, and set the corresponding Checkbox state

QModelIndexList indexes() const List of QModelIndex cells in the selection range

  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 will automatically send out the itemChanged signal when the cell is changed . Set the slot function OnCheckBoxItemChanged to process the signal to select the row.

It should be noted that QStandardItem can get the row number, tableView has a function to directly select the specified row, but no function is found that does not select the specified row.

So you have to find QModelIndex according to QStandardItem, and then don't select a row according to QModelIndex. When you don't select a row, it needs to be QItemSelectionModel.Deselect|QItemSelectionModel.Rows, otherwise you can only not select the first cell.

QModelIndex indexFromItem(const QStandardItem *item) const Query the QModelIndex of the specified QStandardItem

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

void itemChanged(QStandardItem *item)

 

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

 

 

Guess you like

Origin blog.csdn.net/bluewhu/article/details/104931196