python - 检测 QTreeView 图标上的点击
问题描述
我有一个QTreeView,其中一些项目用图标装饰。这些项目可以在 TreeView 的任何列中。
我想知道如何检测鼠标点击图标。我可以使用视图的mousePressEvent()来检测鼠标按下,我可以通过使用Qt.DecorationRole调用模型的data()方法来检查单击的项目中是否存在图标,以查看是否返回一个空的QVariant,并且我可以使用视图的iconSize()方法查询图标的大小。但我无法知道项目的视觉矩形内图标的坐标。
PS。其他与 QTreeView 装饰有关的 SO 问题通常是指树折叠和展开图标,与此问题无关。
解决方案
逻辑是有2个数据:
- 鼠标点击的位置,可以在delegate的editorEvent方法中获取。
- 使用 StyleOptionViewItem 和用于绘画的 QStyle 获得的图标的位置。
from PyQt5 import QtCore, QtGui, QtWidgets
class Delegate(QtWidgets.QStyledItemDelegate):
def editorEvent(self, event, model, option, index):
ret = super().editorEvent(event, model, option, index)
if event.type() == QtCore.QEvent.MouseButtonPress:
self.initStyleOption(option, index)
widget = option.widget
style = (
widget.style() if widget is not None else QtWidgets.QApplication.style()
)
icon_rect = style.subElementRect(
QtWidgets.QStyle.SE_ItemViewItemDecoration, option, widget
)
if icon_rect.contains(event.pos()):
print("icon clicked")
return ret
def main():
app = QtWidgets.QApplication([])
pixmap = QtGui.QPixmap(128, 128)
pixmap.fill(QtCore.Qt.green)
icon = QtGui.QIcon(pixmap)
model = QtGui.QStandardItemModel()
for i in range(5):
item = QtGui.QStandardItem(f"item-{i}")
item.setIcon(icon)
item.setEditable(False)
model.appendRow(item)
for j in range(6):
child_item = QtGui.QStandardItem(f"item {i}{j}")
child_item.setIcon(icon)
child_item.setEditable(False)
item.appendRow(child_item)
w = QtWidgets.QTreeView()
w.setModel(model)
w.expandAll()
delegate = Delegate(w)
w.setItemDelegate(delegate)
w.resize(640, 480)
w.show()
app.exec_()
if __name__ == "__main__":
main()
推荐阅读
- sql-server - SQL Server 如何分解视图代码并选择要提取的正确表?
- c# - Sql 不会使用 web 方法和 linq 更新
- ruby-on-rails - Rails 测试为所有失败的测试重复错误消息
- c# - 是否有用于匹配不超过 2 个重复字符的字符串的正则表达式?
- python - 使用 TensorFlow 和 flow_from_directory 计算 CNN 的准确度
- c - 在 uint8_t 块的特定索引处添加位
- regex - 与 EXACTLY 2 '*' 匹配的行的 Grep 命令
- java - 我应该使用类还是数据结构来存储这些数据
- javascript - 是否可以从目录中导入所有类并初始化它们?
- java - 如何将图像包含到可执行的 .jar 中?