目标
我希望用户能够点击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"))
之类的东西作为调用函数中的一个输入。它不起作用,我只包括它来显示我希望找到的那种解决方案。
可能相关的帖子:
答案 0 :(得分:1)
您无法为QIcon
重新实现事件处理程序,因为它是图像的简单容器,与事件处理无关。这就是为什么你的QIcon
课程没有做任何事情的原因。
默认情况下,QTreeView
仅绘制装饰图标。
您可以在树视图中使用自定义项委托。
QTreeView
继承自QAbstractItemView
,其中包含多个setItemDelegate
方法(documentation)。然后扩展QItemDelegate
或实施QAbstractItemDelegate
。
使用setIndexWidget()
设置自定义小部件可能会快一些。
如果图标始终相同,您甚至可以使用QTreeView
上的样式表。 (documentation)