You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:45:12