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