PyQt5:QStyledItemDelegate中State_MouseOver在QTableView内的光标异常问题
解决QStyledItemDelegate光标未恢复的问题
问题根源
你当前用QApplication.setOverrideCursor()全局设置光标,这种方式依赖代理的initStyleOption被调用才能触发恢复逻辑。但鼠标移到表头时,表头不属于代理的处理范围,代理不会触发initStyleOption,所以restoreOverrideCursor()根本没执行,光标就停留在手型状态了。另外,setOverrideCursor和restoreOverrideCursor是栈式操作,调用次数不匹配也会导致光标无法正确恢复。
正确实现方式
不要用全局光标设置,直接修改QStyleOptionViewItem的cursor属性,让Qt自动负责光标切换,这才是代理的标准用法:
from PyQt5 import QtWidgets from PyQt5 import QtGui, QtCore class ReportDelegate(QtWidgets.QStyledItemDelegate): def initStyleOption(self, option, index): super().initStyleOption(option, index) # 仅在鼠标悬停第8列、行号有效且单元格有文本时,设置手型光标 if (option.state & QtWidgets.QStyle.State_MouseOver and index.column() == 8 and index.row() >= 0 and option.text): option.cursor = QtGui.QCursor(QtCore.Qt.PointingHandCursor) # 其他场景无需额外处理,Qt会自动切换回默认光标
补充说明
- 这种方式不需要手动恢复光标,Qt会根据当前鼠标所在区域的状态自动切换,包括移到表头、其他列时,都会自动恢复默认光标。
- 代码里把类名改成了
ReportDelegate,符合PEP8命名规范,可读性更强。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

