Python在QTableView中添加复选框以及下拉框(可单击实现编辑)

发布时间 2023-07-21 17:02:46作者: 夜轻寒-L

1、添加复选框(居中显示、单击即可选则/取消)

  1 # -*- coding: utf-8 -*-
  2 
  3 # Form implementation generated from reading ui file 'test_pyqt5_4.ui'
  4 #
  5 # Created by: PyQt5 UI code generator 5.15.9
  6 #
  7 # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  8 # run again.  Do not edit this file unless you know what you are doing.
  9 
 10 
 11 from PyQt5 import QtCore, QtWidgets
 12 from PyQt5.QtGui import QStandardItemModel, QStandardItem
 13 from PyQt5.QtCore import Qt, QEvent
 14 from PyQt5.QtWidgets import QStyle
 15 
 16 '''
 17     实现表格内列放置复选框
 18 '''
 19 
 20 class My_CheckBox_Delegate(QtWidgets.QStyledItemDelegate):
 21     def __init__(self, parent = None):
 22         super(My_CheckBox_Delegate, self).__init__(parent)
 23 
 24     def editorEvent(self, event, model, option, index):
 25         if not int(index.flags() & Qt.ItemIsEditable) > 0:
 26             return False
 27 
 28         if event.type() == QEvent.MouseButtonRelease and event.button() == Qt.LeftButton:
 29             # Change the checkbox-state
 30             model.setData(index, 1 if index.data(Qt.DisplayRole) == 0 else 0)
 31             return True
 32 
 33         return False
 34 
 35     def createEditor(self, parent, option, index):
 36         return None
 37 
 38     # 计算 check_box的位置 和 大小
 39     def checkBoxRect(self, option):
 40         but_style = QtWidgets.QStyleOptionButton()
 41         check_box_rect = QtWidgets.QApplication.style().subElementRect(
 42             QStyle.SE_CheckBoxIndicator,
 43             but_style)
 44 
 45         check_box_point = QtCore.QPoint(int(option.rect.x() +
 46                                         option.rect.width() / 2 -
 47                                         check_box_rect.width() / 2),
 48                                         int(option.rect.y() +
 49                                         option.rect.height() / 2 -
 50                                         check_box_rect.height() / 2))
 51         return QtCore.QRect(check_box_point, check_box_rect.size())
 52 
 53     def paint(self, painter, option, index):
 54         # 获取值
 55         checked = index.model().data(index, Qt.DisplayRole)
 56         # 按钮的风格选项
 57         checkBoxOption = QtWidgets.QStyleOptionButton()
 58         checkBoxOption.state |= QStyle.State_Enabled
 59         # 根据值判断是否选中
 60         if checked is not None and checked > 0:
 61             checkBoxOption.state |= QStyle.State_On
 62         else:
 63             checkBoxOption.state |= QStyle.State_Off
 64 
 65         # 返回QCheckBox几何形状
 66         checkBoxOption.rect = self.checkBoxRect(option)
 67         # 绘制QCheckBox
 68         QtWidgets.QApplication.style().drawControl(QStyle.CE_CheckBox, checkBoxOption, painter)
 69 
 70     def setEditorData(self, editor, index):
 71         data = index.data()
 72         if data > 0:
 73             editor.setChecked(True)
 74         else:
 75             editor.setChecked(False)
 76 
 77     def setModelData(self, editor, model, index):
 78         data = editor.isChecked()
 79         if data:
 80             model.setData(index, 1)
 81         else:
 82             model.setData(index, 0)
 83 
 84     def updateEditorGeometry(self, editor, option, index):
 85         editor.setGeometry(option.rect)
 86 
 87 class Ui_Form(object):
 88     def setupUi(self, Form):
 89         Form.setObjectName("Form")
 90         Form.setEnabled(True)
 91         Form.resize(600, 400)
 92         Form.setMinimumSize(QtCore.QSize(600, 400))
 93         Form.setMaximumSize(QtCore.QSize(600, 400))
 94         self.frame = QtWidgets.QFrame(Form)
 95         self.frame.setGeometry(QtCore.QRect(0, 0, 600, 400))
 96         self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 97         self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
 98         self.frame.setObjectName("frame")
 99         self.tableView = QtWidgets.QTableView(self.frame)
100         self.tableView.setGeometry(QtCore.QRect(0, 25, 600, 375))
101         self.tableView.setObjectName("tableView")
102         self.toolBar = QtWidgets.QToolBar(self.frame)
103         self.toolBar.setGeometry(QtCore.QRect(0, 0, 600, 25))
104         self.toolBar.setObjectName("toolBar")
105         self.add_table_row = QtWidgets.QAction(Form)
106         self.add_table_row.setObjectName("add_table_row")
107         self.del_table_row = QtWidgets.QAction(Form)
108         self.del_table_row.setObjectName("del_table_row")
109         self.toolBar.addAction(self.add_table_row)
110         self.toolBar.addAction(self.del_table_row)
111 
112         # 设置表格初始化模型
113         self.model = QStandardItemModel(4, 4)
114         # 设置表头方式
115         self.model.setHorizontalHeaderLabels(['第一列', '第二列', '第三列', '第四列'])
116         # 隐藏默认的行号
117         hearder = self.tableView.verticalHeader()
118         hearder.hide()
119         # 添加数据
120         for row in range(4):
121             # 第一列设值一定要设置Data的形式,不然代理里头paint方法读取不到index.Data()值
122             self.model.setData(self.model.index(row, 0), 0)
123             for column in range(1, 4):
124                 item = QStandardItem('%s' % (row*column))
125                 # 设置每个位置的文本值
126                 self.model.setItem(row, column, item)
127         # QTableView 绑定 数据
128         self.tableView.setModel(self.model)
129 
130         # 水平方向标签拓展剩下的窗口部分,填满表格
131         self.tableView.horizontalHeader().setStretchLastSection(True)
132         # 水平方向,表格大小拓展到适当的尺寸
133         self.tableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
134         # 设置只能选择一个对象
135         self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
136         # 设置不可编辑
137         # self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
138         # 设置只有行选中
139         self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
140         # 设置表头底部边框
141         self.tableView.horizontalHeader().setStyleSheet('border:none;border-bottom:1px solid #D8D8D8')
142         # 设置添加行、删除行响应事件
143         self.toolBar.actionTriggered.connect(self.toolbar_click)
144         # 设置第一列为复选框
145         self.tableView.setItemDelegateForColumn(0, My_CheckBox_Delegate())
146 
147         self.retranslateUi(Form)
148         QtCore.QMetaObject.connectSlotsByName(Form)
149 
150     def retranslateUi(self, Form):
151         _translate = QtCore.QCoreApplication.translate
152         Form.setWindowTitle(_translate("Form", "Form"))
153         self.toolBar.setProperty("text", _translate("Form", "..."))
154         self.add_table_row.setText(_translate("Form", "添加"))
155         self.add_table_row.setToolTip(_translate("Form", "添加行"))
156         self.del_table_row.setText(_translate("Form", "删除"))
157         self.del_table_row.setToolTip(_translate("Form", "删除行"))
158 
159     def toolbar_click(self, action):
160         if action.text() == '添加':
161             self.tableAddInfo()
162         elif action.text() == '删除':
163             self.tableRemoveInfo()
164 
165     def tableAddInfo(self):
166         # 获取表格数据行数
167         rowcount = self.tableView.model().rowCount()
168         # 添加
169         for column in range(1, 4):
170             item = QStandardItem('%s' % (rowcount*column))
171             # 设置每个位置的文本值
172             self.model.setItem(rowcount, column, item)
173         # 一定要将设置Data写在setItem后,不然代理里头paint方法读取不到index.Data()值,可能是和初始化表格设置了行数有关
174         self.model.setData(self.model.index(rowcount, 0), 0)
175 
176     def tableRemoveInfo(self):
177         if self.tableView.selectionModel().selection().count() > 0:
178             # 获取选中行
179             rowIndex = self.tableView.selectionModel().selectedRows()
180             # 获取选中行的行号
181             indexSort = [index.row() for index in rowIndex]
182             # 行号按照从大到小排序
183             indexSort.sort(reverse = True)
184             for index in indexSort:
185                 self.model.removeRow(index)
186 
187 if __name__ == "__main__":
188     import sys
189     app = QtWidgets.QApplication(sys.argv)
190     Form = QtWidgets.QWidget()
191     ui = Ui_Form()
192     ui.setupUi(Form)
193     Form.show()
194     sys.exit(app.exec_())

2、添加下拉框(单击即可打开下拉框选值)

  1 # -*- coding: utf-8 -*-
  2 
  3 # Form implementation generated from reading ui file 'test_pyqt5_4.ui'
  4 #
  5 # Created by: PyQt5 UI code generator 5.15.9
  6 #
  7 # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  8 # run again.  Do not edit this file unless you know what you are doing.
  9 
 10 
 11 from PyQt5 import QtCore, QtWidgets
 12 from PyQt5.QtCore import Qt, QEvent
 13 from PyQt5.QtGui import QStandardItemModel, QStandardItem
 14 from PyQt5.QtWidgets import QStyle, QApplication
 15 
 16 '''
 17     实现表格内列放置下拉框
 18 '''
 19 
 20 class My_ComboBox_Delegate(QtWidgets.QStyledItemDelegate):
 21     def __init__(self, parent = None):
 22         super(My_ComboBox_Delegate, self).__init__(parent)
 23 
 24     def editorEvent(self, event, model, option, index):
 25         if not int(index.flags() & Qt.ItemIsEditable) > 0:
 26             return False
 27 
 28         if event.type() == QEvent.MouseButtonRelease and event.button() == Qt.LeftButton:
 29             # 代码设置单元格编辑,以便触发下面的createEditor,创建下拉框控件视图
 30             option.widget.edit(index)
 31             return True
 32 
 33         return False
 34 
 35     def createEditor(self, parent, option, index):
 36         data = index.data()
 37         comboBox = QtWidgets.QComboBox(parent)
 38         comboBox.addItems(['1', '2', '3', '4'])
 39         comboBox.setCurrentText(data)
 40 
 41         return comboBox
 42 
 43     def paint(self, painter, option, index):
 44         super(C_Delegate, self).paint(painter, option, index)
 45 
 46     def setEditorData(self, editor, index):
 47         super(C_Delegate, self).setEditorData(editor, index)
 48 
 49     def setModelData(self, editor, model, index):
 50         data = editor.currentText()
 51         model.setData(index, data, Qt.EditRole)
 52 
 53     def updateEditorGeometry(self, editor, option, index):
 54         editor.setGeometry(option.rect)
 55         # 在界面正确显示创建的下拉框视图时,将下拉框展开,以便选择
 56         editor.showPopup()
 57 
 58 class Ui_Form(object):
 59     def setupUi(self, Form):
 60         Form.setObjectName("Form")
 61         Form.setEnabled(True)
 62         Form.resize(600, 400)
 63         Form.setMinimumSize(QtCore.QSize(600, 400))
 64         Form.setMaximumSize(QtCore.QSize(600, 400))
 65         self.frame = QtWidgets.QFrame(Form)
 66         self.frame.setGeometry(QtCore.QRect(0, 0, 600, 400))
 67         self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
 68         self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
 69         self.frame.setObjectName("frame")
 70         self.tableView = QtWidgets.QTableView(self.frame)
 71         self.tableView.setGeometry(QtCore.QRect(0, 25, 600, 375))
 72         self.tableView.setObjectName("tableView")
 73         self.toolBar = QtWidgets.QToolBar(self.frame)
 74         self.toolBar.setGeometry(QtCore.QRect(0, 0, 600, 25))
 75         self.toolBar.setObjectName("toolBar")
 76         self.add_table_row = QtWidgets.QAction(Form)
 77         self.add_table_row.setObjectName("add_table_row")
 78         self.del_table_row = QtWidgets.QAction(Form)
 79         self.del_table_row.setObjectName("del_table_row")
 80         self.toolBar.addAction(self.add_table_row)
 81         self.toolBar.addAction(self.del_table_row)
 82 
 83         # 设置表格初始化模型
 84         self.model = QStandardItemModel(4, 4)
 85         # 设置表头方式
 86         self.model.setHorizontalHeaderLabels(['第一列', '第二列', '第三列', '第四列'])
 87         # 隐藏默认的行号
 88         hearder = self.tableView.verticalHeader()
 89         hearder.hide()
 90         # 添加数据
 91         for row in range(4):
 92             self.model.setItem(row, 0, QStandardItem('1'))
 93             for column in range(1, 4):
 94                 item = QStandardItem('%s' % (row*column))
 95                 # 设置每个位置的文本值
 96                 self.model.setItem(row, column, item)
 97         # QTableView 绑定 数据
 98         self.tableView.setModel(self.model)
 99 
100         # 水平方向标签拓展剩下的窗口部分,填满表格
101         self.tableView.horizontalHeader().setStretchLastSection(True)
102         # 水平方向,表格大小拓展到适当的尺寸
103         self.tableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
104         # 设置只能选择一个对象
105         self.tableView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
106         # 设置不可编辑
107         #self.tableView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
108         # 设置只有行选中
109         self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
110         # 设置表头底部边框
111         self.tableView.horizontalHeader().setStyleSheet('border:none;border-bottom:1px solid #D8D8D8')
112         # 设置添加行、删除行响应事件
113         self.toolBar.actionTriggered.connect(self.toolbar_click)
114         # 设置第一列为下拉框
115         self.tableView.setItemDelegateForColumn(0, My_ComboBox_Delegate())
116 
117         self.retranslateUi(Form)
118         QtCore.QMetaObject.connectSlotsByName(Form)
119 
120     def retranslateUi(self, Form):
121         _translate = QtCore.QCoreApplication.translate
122         Form.setWindowTitle(_translate("Form", "Form"))
123         self.toolBar.setProperty("text", _translate("Form", "..."))
124         self.add_table_row.setText(_translate("Form", "添加"))
125         self.add_table_row.setToolTip(_translate("Form", "添加行"))
126         self.del_table_row.setText(_translate("Form", "删除"))
127         self.del_table_row.setToolTip(_translate("Form", "删除行"))
128 
129     def toolbar_click(self, action):
130         if action.text() == '添加':
131             self.tableAddInfo()
132         elif action.text() == '删除':
133             self.tableRemoveInfo()
134 
135     def tableAddInfo(self):
136         # 获取表格数据行数
137         rowcount = self.tableView.model().rowCount()
138         # 添加
139         self.model.setItem(rowcount, 0, QStandardItem('1'))
140         for column in range(1, 4):
141             item = QStandardItem('%s' % (rowcount*column))
142             # 设置每个位置的文本值
143             self.model.setItem(rowcount, column, item)
144 
145     def tableRemoveInfo(self):
146         if self.tableView.selectionModel().selection().count() > 0:
147             # 获取选中行
148             rowIndex = self.tableView.selectionModel().selectedRows()
149             # 获取选中行的行号
150             indexSort = [index.row() for index in rowIndex]
151             # 行号按照从大到小排序
152             indexSort.sort(reverse = True)
153             for index in indexSort:
154                 self.model.removeRow(index)
155 
156 if __name__ == "__main__":
157     import sys
158     app = QtWidgets.QApplication(sys.argv)
159     Form = QtWidgets.QWidget()
160     ui = Ui_Form()
161     ui.setupUi(Form)
162     Form.show()
163     sys.exit(app.exec_())