如何使QIcon可点击?

时间:2014-07-21 21:23:01

标签: python qt pyqt pyside

目标

我希望用户能够点击QIcon来做某事。也就是说,我想在QIcon中将鼠标单击事件连接到插槽。

我尝试了什么

在我的示例(下面)中,我使用的是树视图,当用户单击其中一个图标时,我想将一个子节点添加到该节点。

我尝试通过重新实现mousePressEvent图标来做到这一点,但我不确定如何在树视图模型中为图标(默认情况下提供纯粹的装饰角色)这样做。

代码以简化形式显示如下:

from PySide import QtGui, QtCore
import icons_rc

class Node(object):
    def __init__(self, name, parentNode=None):
        self.name = name
        self.childNodes = []  
        self.parentNode = parentNode
        if parentNode is not None:  #if self has a parent, then add self node to parent in tree
            parentNode.addChild(self)

    def addChild(self, childNode):
        self.childNodes.append(childNode)  #

    def setName(self, name):
        self.name=name

    def data(self):
        return self.name

    def child(self, row):
        return self.childNodes[row]

    def childCount(self):
        return len(self.childNodes)

    def parent(self):
        return self.parentNode

    def row(self):
        if self.parentNode is not None: #if self has a parent, then return  row of self
            return self.parentNode.childNodes.index(self)


class TreeModel(QtCore.QAbstractItemModel):
    #Inputs: node, Qobject
    def __init__(self, root, parent=None):
        QtCore.QAbstractItemModel.__init__(self, parent)
        self.rootNode = root

    def rowCount(self, parentIndex=QtCore.QModelIndex()):
        if not parentIndex.isValid():
            parentNode = self.rootNode
        else:
            parentNode = parentIndex.internalPointer()  #picks out parent node of tree
        return parentNode.childCount()

    def columnCount(self, parentIndex=QtCore.QModelIndex()):
        return 1

    def flags(self,index):
        return QtCore.Qt.ItemIsEnabled

    def data(self, index, role):
        if not index.isValid():
            return None

        node=index.internalPointer()
        #role--editrole here so text doesn't disappear when you double click
        if role == QtCore.Qt.DisplayRole:
            if index.column() == 0:
                return node.data()  #node.data method defined above (string)

        #icons are shown by using a decoration role
        if role==QtCore.Qt.DecorationRole:
            if index.column() == 0:
                return QtGui.QIcon(QtGui.QPixmap(":/images/add.png"))

    def setData(self, index, value, role=QtCore.Qt.EditRole):
        if index.isValid():
            return  True
        else:
            return False

    def getNode(self,index):
        if index.isValid():
            node=index.internalPointer()
            if node:
                return node
        return self.rootNode

    def parent(self, childIndex):
        if not childIndex.isValid(): 
            return QtCore.QModelIndex()
        childNode = self.getNode(childIndex) 
        parentNode = childNode.parent()  
        if parentNode == self.rootNode:
            return QtCore.QModelIndex()
        return self.createIndex(parentNode.row(), 0, parentNode)

    def index(self, row, column, parentIndex):
        if not self.hasIndex(row, column, parentIndex):
            return QtCore.QModelIndex()
        parentNode=self.getNode(parentIndex)
        childNode = parentNode.child(row)  #implemented above
        if childNode:
            return self.createIndex(row, 0, childNode) #row/col/object yields index
        else:
            return QtCore.QModelIndex()


def main():
    import sys
    qtApp=QtGui.QApplication(sys.argv)

    rootNode = Node("Hips")  #for some reason, by design, this will not show
    childNode0 = Node("LeftLeg", rootNode)
    childNode1 = Node("RightLeg", rootNode)
    childNode2 = Node("RightAnkle", childNode1)
    childNode3 = Node("Middle toe", childNode2)
    childNode4 = Node("Pirate flank toe", childNode2)
    childNode5 = Node("Pinky toe", childNode2)

    model=TreeModel(rootNode)
    treeView = QtGui.QTreeView()
    treeView.show()  #opens empty window
    treeView.setModel(model)

    sys.exit(qtApp.exec_())

if __name__ == "__main__":
    main()

基本上我想构建一个事件处理程序,当我点击一个图标时添加一个子项,这个图标在add.png中给出。是否有一些偷偷摸摸的路线重新实现mouseClickEvent或其他功能的图标?我在谷歌这个问题上取得了一些进展。

我尝试了继承QIcon,并重新实现了mousePressEvent。目标是在TreeModel.data()中使用此修订的图标类。到目前为止,我没有运气让班上班。这是我试过的:

class ClickableQIcon(QtGui.QIcon):

    def __init__(self, iconPixmap, parent):
        QtGui.QIcon.__init__(self, iconPixmap, parent)      

    def mousePressEvent(self, event):
        print "This time you pressed in an icon"   

我会将iconPixmap=QtGui.QIcon(QtGui.QPixmap(":/images/add.png"))之类的东西作为调用函数中的一个输入。它不起作用,我只包括它来显示我希望找到的那种解决方案。

可能相关的帖子:

Button Icon Change on Click

QIcon inside combobox

1 个答案:

答案 0 :(得分:1)

您无法为QIcon重新实现事件处理程序,因为它是图像的简单容器,与事件处理无关。这就是为什么你的QIcon课程没有做任何事情的原因。

默认情况下,QTreeView仅绘制装饰图标。

您可以在树视图中使用自定义项委托。 QTreeView继承自QAbstractItemView,其中包含多个setItemDelegate方法(documentation)。然后扩展QItemDelegate或实施QAbstractItemDelegate

使用setIndexWidget()设置自定义小部件可能会快一些。

如果图标始终相同,您甚至可以使用QTreeView上的样式表。 (documentation