如何实现QTableView单元格悬停切换光标且移出后自动恢复样式
解决方案
问题根因
entered信号仅在鼠标进入单元格时触发,当鼠标直接移出整个QTableView控件范围时,不会触发该信号,因此没有执行重置光标的逻辑,导致手型光标残留。
修复步骤
- 自定义继承自
QTableView的子类,重写leaveEvent方法,鼠标离开控件时主动重置光标为箭头样式 - 原有
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
相关产品推荐
相关产品推荐

