如何用PySide6实现仅编辑QTableView指定单元格
PySide6 QTableView 动态控制编辑与焦点权限实现方案
核心思路
- 初始状态:设置QTableView的
focusPolicy为Qt.NoFocus,同时让模型默认返回不可编辑的flags。 - 解锁按钮点击时:修改view的
focusPolicy为Qt.StrongFocus(允许获取焦点),并标记允许指定单元格(如(1,1))的编辑权限。 - 恢复按钮点击时:重置view的
focusPolicy为Qt.NoFocus,取消所有单元格的编辑权限。
完整代码实现
from PySide6.QtWidgets import (QApplication, QMainWindow, QTableView, QPushButton, QVBoxLayout, QWidget) from PySide6.QtCore import Qt, QModelIndex, QStandardItemModel class EditableModel(QStandardItemModel): def __init__(self, parent=None): super().__init__(parent) # 标记是否处于解锁状态,以及允许编辑的单元格 self._unlocked = False self._editable_cell = (1, 1) # 指定可编辑的行、列(注意行和列从0开始) def flags(self, index: QModelIndex) -> Qt.ItemFlags: base_flags = super().flags(index) if not self._unlocked: # 锁定状态:移除编辑权限 return base_flags & ~Qt.ItemIsEditable # 解锁状态:检查是否是指定单元格,是的话添加编辑权限 if index.row() == self._editable_cell[0] and index.column() == self._editable_cell[1]: return base_flags | Qt.ItemIsEditable # 其他单元格仍不可编辑 return base_flags & ~Qt.ItemIsEditable class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("QTableView 权限控制") central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) # 初始化表格和模型 self.table_view = QTableView() self.model = EditableModel() # 填充测试数据:3行3列 self.model.setRowCount(3) self.model.setColumnCount(3) for row in range(3): for col in range(3): self.model.setData(self.model.index(row, col), f"({row},{col})") self.table_view.setModel(self.model) # 初始状态:不可获取焦点、不可编辑 self.table_view.setFocusPolicy(Qt.NoFocus) # 创建按钮 self.unlock_btn = QPushButton("解锁并允许编辑(1,1)") self.unlock_btn.clicked.connect(self.unlock_table) self.restore_btn = QPushButton("恢复禁用限制") self.restore_btn.clicked.connect(self.restore_table) # 添加到布局 layout.addWidget(self.table_view) layout.addWidget(self.unlock_btn) layout.addWidget(self.restore_btn) def unlock_table(self): # 1. 允许表格获取焦点 self.table_view.setFocusPolicy(Qt.StrongFocus) # 2. 标记解锁状态,触发模型flags更新 self.model._unlocked = True # 更新指定单元格的显示,确保权限生效 self.model.dataChanged.emit(self.model.index(1,1), self.model.index(1,1)) def restore_table(self): # 恢复焦点限制 self.table_view.setFocusPolicy(Qt.NoFocus) # 取消解锁状态 self.model._unlocked = False # 更新所有单元格的显示 self.model.dataChanged.emit(self.model.index(0,0), self.model.index(2,2)) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec()
关键说明
- 模型重写
flags方法:通过内部状态_unlocked控制单元格的编辑权限,只有在解锁状态且是指定单元格时,才允许编辑。 - 焦点控制:通过修改
QTableView的focusPolicy属性,切换是否允许表格获取焦点,初始设为Qt.NoFocus,解锁时设为Qt.StrongFocus。 - 数据变更通知:修改状态后调用
dataChanged信号,确保表格刷新单元格的权限状态。
内容的提问来源于stack exchange,提问作者Garp
相关产品推荐
相关产品推荐

