Reputation: 1567
I have a QTreeView in which some items are decorated with an icon. The items could be in any column of the TreeView.
I wish to know how to detect mouse clicks on an icon. I can use the view's mousePressEvent() to detect a mouse press, I can check whether an icon is present in the clicked item by calling the model's data() method with Qt.DecorationRole to see whether I get an empty QVariant back, and I can query the size of the icon using the view's iconSize() method. But I have no way of knowing the co-ordinates of the icon within the item's visual rectangle.
PS. Other SO questions relating to QTreeView decorations usually refer to the tree collapse and expand icons, and have no bearing on this question.
Upvotes: 1
Views: 987
Reputation: 244301
The logic is to have 2 data:
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()
Upvotes: 2
Reputation: 2268
In c++ QT this can be achieved through this method , must be similar in python also.
If you draw the icon in paint you must know the location.
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;
}
Upvotes: 1