【问题标题】:Detecting clicks on QTreeView icons检测 QTreeView 图标上的点击
【发布时间】:2019-04-24 22:22:51
【问题描述】:

我有一个 QTreeView,其中一些项目用图标装饰。这些项目可以在 TreeView 的任何列中。

我想知道如何检测鼠标点击图标。我可以使用视图的 mousePressEvent() 来检测鼠标按下,我可以通过调用模型的 data() 方法来检查点击的项目中是否存在图标 data() em>Qt.DecorationRole 来查看我是否得到一个空的 QVariant,我可以使用视图的 iconSize() 方法查询图标的大小。但我无法知道图标在项目的视觉矩形内的坐标。

附言。其他与 QTreeView 装饰有关的 SO 问题通常是指树 collapseexpand 图标,与此问题无关。

【问题讨论】:

  • 问题是检测鼠标点击 - 在我的情况下,我将根据模型中的数据执行操作,但这与问题无关。第二部分是相关的,因为项目中图标的位置由其样式控制-但我认为您的观点是它没有给问题增加任何内容,因此我将其删除。谢谢。
  • 如果可能的话,只需将图标放在单独的列中即可。否则你需要处理很多不同的情况,你会得到一个通用的答案。因为图标可能具有不同的大小或位置。我同意@eyllanesc - 您可以查看drawControl 的源代码并以某种方式预测图标位置。

标签: python qt pyqt qtreeview


【解决方案1】:

在c++ QT中可以通过这个方法实现,在python中也应该类似。

如果你在paint中绘制图标,你必须知道位置。

https://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent.

bool PixelDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QMouseEvent* mouseEvent = (QMouseEvent*) event;
    QPoint p =  mouseEvent->pos();   // Position of mouse click.    
    
    return false;
}

【讨论】:

    【解决方案2】:

    逻辑是有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()
    

    【讨论】:

      猜你喜欢
      • 2021-04-15
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 2015-04-04
      • 2021-09-06
      • 2015-08-03
      相关资源
      最近更新 更多