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

 

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章