PyQt5创建复选框

本文展示了如何使用PyQt5库创建和管理复选框控件(QCheckBox)。通过实例代码,详细解释了复选框的三种状态:未选中、半选中和选中,并演示了如何响应复选框状态改变的事件,实时更新状态信息。

PyQt5创建复选框

# @Time : 2021/4/10 15:41 

# @Author : Kevin

# @File : 复选框.py 

# @Software: PyCharm

# encoding = utf-8

"""
复选框控件 (QCheckBox)

3种状态

未选中: 0
半选中: 1
选中: 2

"""
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt

class QCheckBoxDemo(QWidget):
    def __init__(self):
        super(QCheckBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('复选框控件演示')
        layout = QHBoxLayout()

        self.checkBox1 = QCheckBox('复选框控件1')
        self.checkBox1.setChecked(True)
        self.checkBox1.stateChanged.connect(lambda: self.checkboxState(self.checkBox1))
        layout.addWidget(self.checkBox1)


        self.checkBox2 = QCheckBox('复选框控件2')
        # self.checkBox2.setChecked(False)
        self.checkBox2.stateChanged.connect(lambda: self.checkboxState(self.checkBox2))
        layout.addWidget(self.checkBox2)


        self.checkBox3 = QCheckBox('复选框控件3')
        # self.checkBox3.setChecked(True)
        self.checkBox3.stateChanged.connect(lambda: self.checkboxState(self.checkBox3))
        self.checkBox3.setTristate(True)
        self.checkBox3.setCheckState(Qt.PartiallyChecked)
        layout.addWidget(self.checkBox3)

        self.setLayout(layout)




    def checkboxState(self, cb):
        check1Status = self.checkBox1.text() + ', is Checked= ' + str(self.checkBox1.isChecked()) + ', checkState= ' + str(self.checkBox1.checkState()) + '\n'
        check2Status = self.checkBox2.text() + ', is Checked= ' + str(self.checkBox2.isChecked()) + ', checkState= ' + str(self.checkBox2.checkState()) + '\n'
        check3Status = self.checkBox3.text() + ', is Checked= ' + str(self.checkBox3.isChecked()) + ', checkState= ' + str(self.checkBox3.checkState()) + '\n'
        print(check1Status + check2Status + check3Status)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QCheckBoxDemo()
    main.show()
    sys.exit(app.exec_())
<think>我们将在QAbstractTableModel中实现个带有复选框列的表格模型。关键点如下: 1. 使用Qt.CheckStateRole来存储和获取复选框的状态。 2. 在data()方法中,对于复选框列,返回Qt.Checked或Qt.Unchecked状态。 3. 在setData()方法中,处理复选框的状态改变。 4. 在flags()方法中,为复选框列添加Qt.ItemIsUserCheckable标志,使其可被用户勾。 假设我们的表格有两列:第列为复选框,第列为显示文本。 步骤: 1. 定义模型类,继承自QAbstractTableModel。 2. 初始化模型数据(例如,个列表,每个元素是个包含字符串和复选框状态的字典或元组)。 3. 实现rowCount(), columnCount()方法。 4. 实现data()方法,根据不同的角色和列返回数据。 5. 实现setData()方法,处理复选框状态的变化。 6. 实现flags()方法,设置每项的标志。 注意:在复选框状态改变时,我们需要发出dataChanged信号。 示例代码:</think># PyQt5 QAbstractTableModel 实现复选框列 在PyQt5中,使用`QAbstractTableModel`实现带有复选框列的表格模型是常见的需求。下面我将详细介绍实现方法,并提供完整示例代码。 ## 实现原理 1. **角色处理**:使用`Qt.ItemDataRole`中的`Qt.CheckStateRole`处理复选框状态 2. **标志设置**:在`flags()`方法中添加`Qt.ItemIsUserCheckable`标志 3. **数据更新**:在`setData()`方法中处理复选框状态变化 4. **状态存储**:使用单独的数据结构存储复选框状态 ## 完整示例代码 ```python import sys from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QVariant from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QVBoxLayout, QWidget class CheckableTableModel(QAbstractTableModel): def __init__(self, data, headers, parent=None): super().__init__(parent) self._data = data # 表格数据 self._headers = headers # 表头 self._checked_states = {} # 存储复选框状态 {行索引: 状态} # 初始化所有行为未中状态 for row in range(len(data)): self._checked_states[row] = Qt.Unchecked def rowCount(self, parent=QModelIndex()): return len(self._data) def columnCount(self, parent=QModelIndex()): return len(self._headers) def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return QVariant() row = index.row() col = index.column() # 第列显示复选框 if col == 0: if role == Qt.CheckStateRole: return self._checked_states.get(row, Qt.Unchecked) elif role == Qt.DisplayRole: return "" # 不显示文本 # 其他列显示数据 if role == Qt.DisplayRole: return self._data[row][col-1] # 第列是复选框,所以减1 return QVariant() def setData(self, index, value, role=Qt.EditRole): if not index.isValid(): return False row = index.row() col = index.column() # 处理复选框状态变化 if col == 0 and role == Qt.CheckStateRole: self._checked_states[row] = value # 通知视图更新 self.dataChanged.emit(index, index, [Qt.CheckStateRole]) return True return False def flags(self, index): flags = super().flags(index) # 第列添加复选框标志 if index.column() == 0: flags |= Qt.ItemIsUserCheckable return flags def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole and orientation == Qt.Horizontal: return self._headers[section] return QVariant() def get_checked_rows(self): """获取中行的索引""" return [row for row, state in self._checked_states.items() if state == Qt.Checked] def get_checked_data(self): """获取中行的数据""" return [self._data[row] for row in self.get_checked_rows()] class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("带复选框的表格模型") self.setGeometry(100, 100, 600, 400) # 创建中央部件 central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) # 创建表格视图 self.tableView = QTableView() layout.addWidget(self.tableView) # 准备数据 headers = ["择", "ID", "名称", "价格"] data = [ [1001, "苹果", 5.99], [1002, "香蕉", 3.49], [1003, "橙子", 4.29], [1004, "葡萄", 8.99], [1005, "西瓜", 12.49] ] # 创建模型并设置 self.model = CheckableTableModel(data, headers) self.tableView.setModel(self.model) # 设置列宽 self.tableView.setColumnWidth(0, 60) # 复选框列 self.tableView.setColumnWidth(1, 100) # ID列 self.tableView.setColumnWidth(2, 200) # 名称列 self.tableView.setColumnWidth(3, 100) # 价格列 # 连接信号 self.model.dataChanged.connect(self.on_data_changed) def on_data_changed(self, topLeft, bottomRight, roles): """当复选框状态改变时触发""" if Qt.CheckStateRole in roles: row = topLeft.row() state = self.model.data(topLeft, Qt.CheckStateRole) item_name = self.model.data(self.model.index(row, 2), Qt.DisplayRole) print(f"行 {row} 状态改变: {'中' if state == Qt.Checked else '未中'} - {item_name}") # 打印所有中项 checked_items = self.model.get_checked_data() print(f"当前中项: {[item[1] for item in checked_items]}") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` ## 关键实现细节 ### 1. 复选框状态存储 ```python self._checked_states = {} # 使用字典存储每行的复选框状态 ``` ### 2. 数据处理方法 ```python def data(self, index, role=Qt.DisplayRole): # 第列处理复选框 if col == 0: if role == Qt.CheckStateRole: return self._checked_states.get(row, Qt.Unchecked) elif role == Qt.DisplayRole: return "" # 不显示文本 ``` ### 3. 状态更新方法 ```python def setData(self, index, value, role=Qt.EditRole): if col == 0 and role == Qt.CheckStateRole: self._checked_states[row] = value self.dataChanged.emit(index, index, [Qt.CheckStateRole]) return True ``` ### 4. 标志设置 ```python def flags(self, index): flags = super().flags(index) if index.column() == 0: flags |= Qt.ItemIsUserCheckable # 添加复选框标志 return flags ``` ## 高级功能扩展 ### 1. 全/全不功能 ```python def select_all(self, state): """全或全不""" for row in range(self.rowCount()): index = self.index(row, 0) self.setData(index, Qt.Checked if state else Qt.Unchecked, Qt.CheckStateRole) ``` ### 2. 三态复选框(部分中) ```python def data(self, index, role=Qt.DisplayRole): if col == 0 and role == Qt.CheckStateRole: # 实现三态逻辑 if self._is_partially_checked(row): return Qt.PartiallyChecked return self._checked_states.get(row, Qt.Unchecked) ``` ### 3. 复选框与数据关联 ```python def get_checked_data(self): """获取中行的完整数据""" return [self._data[row] for row in self.get_checked_rows()] ``` ## 性能优化建议 1. **批量更新**: ```python def set_checked_rows(self, rows, state): """批量设置行中状态""" self.layoutAboutToBeChanged.emit() # 通知布局即将改变 for row in rows: self._checked_states[row] = state self.layoutChanged.emit() # 通知布局已改变 ``` 2. **数据分页**: ```python def load_data_page(self, page, page_size): """分页加载数据""" self.beginResetModel() self._data = self.fetch_data(page, page_size) self.endResetModel() ``` 3. **异步加载**: ```python class DataLoader(QThread): dataLoaded = pyqtSignal(list) def run(self): data = fetch_large_dataset() # 耗时操作 self.dataLoaded.emit(data) ``` ## 常见问题解决 ### 1. 复选框不显示 - 检查`flags()`方法是否添加了`Qt.ItemIsUserCheckable` - 确保`data()`方法对`Qt.CheckStateRole`返回了有效值 ### 2. 状态不更新 - 确认`setData()`方法在修改状态后返回`True` - 确保发出了`dataChanged`信号 ### 3. 性能问题 - 大数据集使用分页加载 - 避免频繁调用`resetModel()`,使用`dataChanged`局部更新 通过以上实现,您可以创建功能完善的带复选框表格模型,并可根据需求进步扩展功能[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值