纳速健身

 找回密码
 注册

扫一扫,访问微社区

查看: 15|回复: 0

[Python] pyqt5 QTableView 添加 checkbox (一)checkbox选择框状态和第一列不分离版

[复制链接]
发表于 2021-1-11 15:37:27 | 显示全部楼层 |阅读模式
参考:
https://blog.csdn.net/yy123xiang/article/details/78739975

代码如下:

  1. import sys
  2. from PyQt5.QtWidgets import (QApplication, QHeaderView, QStyle, QStyleOptionButton, QTableView)
  3. from PyQt5.QtCore import (pyqtSignal, Qt, QAbstractTableModel, QModelIndex, QRect, QVariant)


  4. # https://wiki.qt.io/Technical_FAQ#How_can_I_insert_a_checkbox_into_the_header_of_my_view.3F
  5. # https://stackoverflow.com/questions/30932528/adding-checkbox-as-vertical-header-in-qtableview

  6. class CheckBoxHeader(QHeaderView):
  7.     clicked = pyqtSignal(bool)

  8.     _x_offset = 3
  9.     _y_offset = 0
  10.     _width = 20
  11.     _height = 20

  12.     def __init__(self, orientation=Qt.Horizontal, parent=None):
  13.         super(CheckBoxHeader, self).__init__(orientation, parent)
  14.         self.isOn = False

  15.     def paintSection(self, painter, rect, logicalIndex):
  16.         painter.save()
  17.         super(CheckBoxHeader, self).paintSection(painter, rect, logicalIndex)
  18.         painter.restore()

  19.         self._y_offset = int((rect.height()-self._width)/2.)

  20.         if logicalIndex == 0:
  21.             option = QStyleOptionButton()
  22.             option.rect = QRect(rect.x() + self._x_offset, rect.y() + self._y_offset, self._width, self._height)
  23.             option.state = QStyle.State_Enabled | QStyle.State_Active
  24.             if self.isOn:
  25.                 option.state |= QStyle.State_On
  26.             else:
  27.                 option.state |= QStyle.State_Off
  28.             self.style().drawControl(QStyle.CE_CheckBox, option, painter)

  29.     def mousePressEvent(self, event):
  30.         index = self.logicalIndexAt(event.pos())
  31.         if 0 == index:
  32.             x = self.sectionPosition(index)
  33.             if x + self._x_offset < event.pos().x() < x + self._x_offset + self._width and self._y_offset < event.pos().y() < self._y_offset + self._height:
  34.                 if self.isOn:
  35.                     self.isOn = False
  36.                 else:
  37.                     self.isOn = True
  38.                 self.clicked.emit(self.isOn)
  39.                 self.update()
  40.         super(CheckBoxHeader, self).mousePressEvent(event)


  41. class MyModel(QAbstractTableModel):
  42.     def __init__(self, parent=None):
  43.         super(MyModel, self).__init__(parent)
  44.         # Keep track of which object are checked
  45.         self.checkList = ['Checked', 'Unchecked']

  46.     def rowCount(self, QModelIndex):
  47.         return len(self.checkList)

  48.     def columnCount(self, QModelIndex):
  49.         return 2

  50.     def data(self, index, role):
  51.         row = index.row()
  52.         col = index.column()
  53.         if role == Qt.DisplayRole:
  54.             return 'Row %d, Column %d' % (row + 1, col + 1)
  55.         elif role == Qt.CheckStateRole:
  56.             if col == 0:
  57.                 return Qt.Checked if self.checkList[row] == 'Checked' else Qt.Unchecked
  58.         elif role == Qt.ToolTipRole:
  59.             if col == 0:
  60.                 return self.checkList[row]
  61.         return QVariant()

  62.     def setData(self, index, value, role):
  63.         row = index.row()
  64.         col = index.column()
  65.         if role == Qt.CheckStateRole and col == 0:
  66.             self.checkList[row] = 'Checked' if value == Qt.Checked else 'Unchecked'
  67.         return True

  68.     def flags(self, index):
  69.         if index.column() == 0:
  70.             return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable
  71.         return Qt.ItemIsEnabled

  72.     def headerData(self, section, orientation, role):
  73.         if role == Qt.DisplayRole:
  74.             if orientation == Qt.Horizontal:
  75.                 if section == 0:
  76.                     return 'Title 1'
  77.                 elif section == 1:
  78.                     return 'Title 2'

  79.     def headerClick(self, isOn):
  80.         self.beginResetModel()
  81.         if isOn:
  82.             self.checkList = ['Checked', 'Checked']
  83.         else:
  84.             self.checkList = ['Unchecked', 'Unchecked']
  85.         self.endResetModel()


  86. if __name__ == '__main__':
  87.     a = QApplication(sys.argv)
  88.     tableView = QTableView()
  89.     myModel = MyModel()
  90.     tableView.setModel(myModel)
  91.     header = CheckBoxHeader()
  92.     tableView.setHorizontalHeader(header)
  93.     #tableView.horizontalHeader().setStretchLastSection(True)
  94.     tableView.horizontalHeader().setStretchLastSection(True)
  95.     tableView.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
  96.     header.clicked.connect(myModel.headerClick)
  97.     tableView.resize(400, 200)
  98.     tableView.show()
  99.     a.exec_()

复制代码



效果如下:
check_box2.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表