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

如何实现QTableView单元格悬停切换光标且移出后自动恢复样式

解决方案

问题根因

entered信号仅在鼠标进入单元格时触发,当鼠标直接移出整个QTableView控件范围时,不会触发该信号,因此没有执行重置光标的逻辑,导致手型光标残留。

修复步骤

  1. 自定义继承自QTableView的子类,重写leaveEvent方法,鼠标离开控件时主动重置光标为箭头样式
  2. 原有entered信号绑定逻辑保留,覆盖表格内单元格切换的场景

修复后完整代码

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

data=[[1,1],[1,2],['a','b']]

class TableModel(QAbstractTableModel):
    def __init__(self, data,header_labels=None):
        super().__init__()
        self._data = data
        self.header_labels=header_labels

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]
    def rowCount(self, index):
        return len(self._data)
    def columnCount(self, index):
        return len(self._data[0])
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if self.header_labels==None:
            self.header_labels=range(len(self._data[0]))
        if role == Qt.DisplayRole and orientation == Qt.Horizontal:
            return self.header_labels[section]
        return QAbstractTableModel.headerData(self, section, orientation, role)

# 自定义TableView,处理鼠标离开事件
class CustomTableView(QTableView):
    def leaveEvent(self, event):
        # 鼠标离开表格时重置光标
        self.setCursor(QCursor(Qt.CursorShape.ArrowCursor))
        super().leaveEvent(event)

def on_entered(index):
    if index.row()==1 and index.column()==1: 
        table.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
    else:
        table.setCursor(QCursor(Qt.CursorShape.ArrowCursor))

app = QApplication(sys.argv)
window = QWidget()
vl=QVBoxLayout(window)

searchbar = QLineEdit()
# 替换为自定义的TableView
table=CustomTableView()
proxy_model = QSortFilterProxyModel()
model = TableModel(data)
proxy_model.setSourceModel(model)
table.setModel(proxy_model)

table.entered.connect(on_entered)
table.setMouseTracking(True)
table.setSelectionMode(QAbstractItemView.NoSelection)
table.setFocusPolicy(Qt.FocusPolicy.NoFocus)

vl.addWidget(table)
t=TableModel(data[1:],data[0])
proxy_model.setSourceModel(t)
window.show()
app.exec_()

可选优化方案

如果不想自定义子类,也可以给原QTableView安装事件过滤器,监听QEvent.Leave事件后重置光标,效果和自定义子类一致。

内容的提问来源于stack exchange,提问作者Viswa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:54:06